While doing some messing around with making a WSGI server, I noticed some test calls to time.sleep() inside a loop were only working the first iteration. Here's a reproduction:
import os
import signal
import time
def run_loop():
i = 0
while True:
print('PID: {}, i = {}'.format(os.getpid(), i))
time.sleep(5) # Only works the first time
i += 1
pid = os.fork() . # May or may not be related?
if pid == 0:
print('PID: {}, CHILD'.format(os.getpid(), i))
os._exit(0)
if __name__ == '__main__':
# If I uncomment this line it works fine.
# If I leave it as is, the time.sleep in run_loop() only waits once.
signal.signal(signal.SIGCHLD, lambda a, b: os.wait())
run_loop()
I am aware of the following part in the time.sleep() documentation.
The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine.
Is this because the SIGCHLD signal keeps triggering while time.sleep() is running? What would cause the signal to cancel every single call to time.sleep() consistently?
from the linux sleep documentation
sleep() causes the calling thread to sleep either until the number of real-time seconds specified in seconds have elapsed or until a signal arrives which is not ignored.
there is a linux c function that allows you to continue sleeping after being interrupted by a signal called 'nanosleep'. it either sleeps a given amount of nanoseconds or sleeps until a signal arrives and returns the number of nanoseconds that remain to be slept but python doesn't expose it in any module
you could simulate the same behavior you would want from nanosleep yourself, something like:
import datetime
import time
def busy_sleep(seconds):
start_time = datetime.datetime.now()
seconds_slept = 0
while seconds_slept < seconds:
time.sleep(seconds - seconds_slept)
seconds_slept = (datetime.datetime.now() - start_time).total_seconds()
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