Python threading: will Event.set() really notify every waiting thread

Criss picture Criss · Jun 6, 2011 · Viewed 26.9k times · Source

If I have a threading.Event and the following two lines of code:

event.set()
event.clear()

and I have some threads who are waiting for that event.

My question is related to what happens when calling the set() method:

  • Can I be ABSOLUTELY sure that all the waiting thread(s) will be notified? (i.e. Event.set() "notifies" the threads)
  • Or could it happen that those two lines are executed so quickly after each other, that some threads might still be waiting? (i.e. Event.wait() polls the event's state, which might be already "cleared" again)

Thanks for your answers!

Answer

Vinay Sajip picture Vinay Sajip · Jun 6, 2011

It's easy enough to verify that things work as expected (Note: this is Python 2 code, which will need adapting for Python 3):

import threading

e = threading.Event()
threads = []

def runner():
    tname = threading.current_thread().name
    print 'Thread waiting for event: %s' % tname
    e.wait()
    print 'Thread got event: %s' % tname

for t in range(100):
    t = threading.Thread(target=runner)
    threads.append(t)
    t.start()

raw_input('Press enter to set and clear the event:')
e.set()
e.clear()
for t in threads:
    t.join()
print 'All done.'

If you run the above script and it terminates, all should be well :-) Notice that a hundred threads are waiting for the event to be set; it's set and cleared straight away; all threads should see this and should terminate (though not in any definite order, and the "All done" can be printed anywhere after the "Press enter" prompt, not just at the very end.