python - threading.Condition.wait(timeout) ignores threading.Condition.notify() -
i have application uses 2 threads. want able shut down both threads waiting condition variable exitcondition
. using python 3.3 unlike python 2.7 makes threading.condition.wait()
return true
when condition notified , false
when timeout occured.
#!/usr/bin/python import threading time import sleep exitcondition = threading.condition() def inputactivity(): while true: exitcondition.acquire() exitconditionreached = exitcondition.wait(.1) #<-critical print(exitconditionreached) exitcondition.release() if exitconditionreached: #exitcondition reached -> shutdown return else: #exitcondition not reached -> work sleep(.1) inthread = threading.thread(target = inputactivity) inthread.start() sleep(.2) #<-critical exitcondition.acquire() exitcondition.notify() print("exitcondition notified") exitcondition.release() inthread.join()
there 2 lines #<-critical
comment in line 10 , 21. if sleep
s "misaligned" (for example .25 , .1) program terminate. if sleep
s "aligned" (for example .2 , .1) inthread
run indefinitely printing false
forever. looks race condition me, apparently if notify
called @ same time wait
notification not recognized. under impression exitcondition.acquire()
, exitcondition.release()
supposed prevent that. question why condition variable not thread safe , can it. ideally want write wait(0)
guarantee no notification swallowed.
if call exitcondition.notify
occurs when worker thread doing work (i.e., in sleep(.1)
call (or anywhere else other .wait
call), behaviour describe sounds i'd expect. wait
call returns true
if notification happened during wait
.
it sounds me though use-case threading.event
instead of threading.condition
: replace threading.condition
threading.event
, replace notify
call set
call, , remove acquire
, release
calls altogether (in both threads).
that is, code should this:
#!/usr/bin/python import threading time import sleep exitcondition = threading.event() def inputactivity(): while true: exitconditionreached = exitcondition.wait(.1) #<-critical print(exitconditionreached) if exitconditionreached: #exitcondition reached -> shutdown return else: #exitcondition not reached -> work sleep(.1) inthread = threading.thread(target = inputactivity) inthread.start() sleep(.2) #<-critical exitcondition.set() print("exitcondition set") inthread.join()
once you've got far, don't need first .wait
: can replace direct is_set
call see if exit condition has been set yet:
#!/usr/bin/python import threading time import sleep exitcondition = threading.event() def inputactivity(): while true: if exitcondition.is_set(): #exitcondition reached -> shutdown return else: #exitcondition not reached -> work sleep(.1) inthread = threading.thread(target = inputactivity) inthread.start() sleep(.2) #<-critical exitcondition.set() print("exitcondition set") inthread.join()
Comments
Post a Comment