-
Notifications
You must be signed in to change notification settings - Fork 986
Closed
Labels
Description
Why?
Corutines are cooperative... and their sleep/waiting on event does not actively use up thread
Why this matter...
it blocks (usualy) main thread... and pyhon sometimes uses main thread to do stuff (like handle os signals)
so it may delay handling signals
Example....
blocking handling signals immediately
import schedule
import signal
import time
from threading import Event
terminateCondition = Event()
def loop():
while not terminateCondition.is_set():
schedule.run_pending()
print("runed")
time.sleep(10)#to increase likeliness that we will interupt during sleep
print("loop exited")
def niceKill(signum,frame): #gets handled immediately
print("killing loop")
terminateCondition.set()
signal.signal(signal.SIGINT, niceKill)
loop() #terminate on ctrl+c after sleep expires but handles signal asapblocking with ocupied main thread
import schedule
import signal
from threading import Event
terminateCondition = Event()
def loop():
while not terminateCondition.wait(10):#to increase likeliness that we will interupt during wait/sleep
schedule.run_pending()
print("runed")
print("loop exited")
def niceKill(signum,frame): #gets handled after wait expires... wait does not allow for signals to get handled
print("killing loop")
terminateCondition.set()
signal.signal(signal.SIGINT, niceKill)
loop() #terminate on on ctrl+c after sleep expiresnon blocking handling signals asap (best option
import asyncio
import schedule
import signal
async def cancelOrWait(event):
"""
returns true if event is set
"""
async def waiter():
await terminateCondition.wait()
try:
return await asyncio.wait_for(event.wait(), timeout=10)#to increase likeliness that we will interupt during wait
except asyncio.TimeoutError:
return False
def makeKiller(event):
def killer(signum, frame):
print("killing loop")
event.set()
return killer
def setupEvent():
terminateCondition = asyncio.Event()
signal.signal(signal.SIGINT,makeKiller(terminateCondition))
return terminateCondition
async def killableLoop(killEvent):
while not await cancelOrWait(killEvent):
print("running")
schedule.run_pending()
print("loop exited")
async def main():
await killableLoop(setupEvent())
asyncio.run(main())#gets terminated imieadly on ctrl+c