Why does while True:
not affect CPU too much in some cases and in other does? How does one prevent that?
I wrote a simple program and was worried that
import threading
import time
#sleeptime = 0.1
while True:
#time.sleep(sleeptime)
if not [thread.name for thread in threading.enumerate() if thread.name == 'control']:
threading.Thread(target=control, name='control').start()
would consume all of computational resources (or at least the cap given by OS) for checking the if statement (most of the time it's false so it should loop quite rapidly) so I initially put system.sleep(sleeptime)
there to avoid that but I was surprised when I removed it it had no measurable effect on system resources. Why?
That brought me to the question how often does the system check the condition.
Naively: If i do something like
import time
i=0
before = time.process_time()
while True:
i += 1
if i >= 100000000: #1e8 but writing 1e8 adds ~ 30% time
break
after = time.process_time()
print(after-before)
on my machine I get 11 seconds and 50% CPU load while running. Why in the second example I get 50% load and nearly nothing on the first one? Is it because of the i += 1
?
Can one profile the while loop (how often it loops and how much resources it consumes) without slowing it down or causing overhead and hence making the measured value irrelevant?
I am doing this on Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32
The process scheduler attempts to maximize CPU usage, and never leave a process starved of CPU time if there are no other processes that need it. So your while loop will use 100% of available idle CPU resources, and will only begin to use less when other CPU intensive processes are started up.
While loop is used to execute a block of code repeatedly until given boolean condition evaluated to False. If we write while True then the loop will run forever.
🔸 How While Loops WorkThe condition is evaluated to check if it's True or False . If the condition is True , the statements that belong to the loop are executed. The while loop condition is checked again. If the condition evaluates to True again, the sequence of statements runs again and the process is repeated.
sleep(1) at the beginning or end of the loop body).
threading.enumerate()
does not affect the current process CPU because of the way it's measured.
But it still polls system resources continuously so even if your process doesn't show high CPU usage, the system is still stressed. It's just that it isn't measured because it's not done within your process execution context, but in the system execution context.
I suggest that you apply a simple time
to your process, which, on Linux, is supposed to print the user & system time. I'm convinced that you'll get a lot of system time in the first example (and none in the second)
Your second example just tells python to perform a CPU intensive loop (because of i+=1
and your test below, but pass
would do the same, except it would be infinite), without system calls, it hogs the CPU all right and it is measured properly by the system.
So in the first case, unless you want a very high reactivity, and you're not running that for too long, I'd suggest that you add a tiny delay between the tests, so the system can have a little break.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With