Because someone else will set it.
You generally start a thread in one part of your application and continue to do whatever you do:
thread = TimerClass()
thread.start()
# Do your stuff
The thread does it's stuff, while you do your stuff. If you want to terminate the thread you just call:
thread.event.set()
And the thread will stop.
So the answer is: event, in this case, is not used for controlling the thread from inside the thread object itself. It is used for controlling the thread from outside (from the object which holds the reference to the thread).
Answer from Viktor Kerkez on Stack OverflowEquivalent of Python threading.Event for sync Rust
multithreading - Python threading: will Event.set() really notify every waiting thread - Stack Overflow
Any harm in idle threads?
Python Threading Tutorial: Basic to Advanced (Multithreading, Pool Executors, Daemon, Lock, Events)
Videos
In the internals of Python, an event is implemented with a Condition() object.
When calling the event.set() method, the notify_all() of the condition is called (after getting the lock to be sure to be not interrupted), then all the threads receive the notification (the lock is released only when all the threads are notified), so you can be sure that all the threads will effectively be notified.
Now, clearing the event just after the notification is not a problem.... until you do not want to check the event value in the waiting threads with an event.is_set(), but you only need this kind of check if you were waiting with a timeout.
Examples :
pseudocode that works :
#in main thread
event = Event()
thread1(event)
thread2(event)
...
event.set()
event.clear()
#in thread code
...
event.wait()
#do the stuff
pseudocode that may not work :
#in main thread
event = Event()
thread1(event)
thread2(event)
...
event.set()
event.clear()
#in thread code
...
while not event.is_set():
event.wait(timeout_value)
#do the stuff
Edited : in python >= 2.7 you can still wait for an event with a timeout and be sure of the state of the event :
event_state = event.wait(timeout)
while not event_state:
event_state = event.wait(timeout)
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.
Are you trying to make your code run faster? In this video, we will be taking a deep dive into python threads from basic to advanced concepts so that you can take advantage of parallelism and concurrency to speed up your program.
-
Python Thread without join()
-
Python Thread with join()
-
Python Thread with Input Arguments
-
Python Multithreading
-
Python Daemon Threads
-
Python Thread with Synchronization using Locks
-
Python Thread Queue Communication between Threads
-
Python Thread Pool Executor
-
Python Thread Events
-
Speed Comparison I/O Task
-
Speed Comparison CPU Task (Multithreading vs Multiprocessing)
https://youtu.be/Rm9Pic2rpAQ
after learning more about asyncio (for IO bound) and multiprocessing (for CPU bound), I start to wonder if there is any real life use case for threading in python. It seems python threading comes with its own baggage, like GIL lock, and it was mentioned that python threading, is not really really multi-thread since due to limitation on interpreters' binding to CPU, only a thread could be scheduled at a time?
This makes me wonder why we even want to use python thread at all?
[SOLVED: use a queue with a poison pill instead of events]
I'm using events to communicate between my main code and a sub-thread. The thread contains a while loop that should get exited once stop_event.set() is called in the main code:
import time
from threading import *
def stream_data(stop_event, new_image_event):
while not stop_event.is_set():
new_image_event.wait()
new_image_event.clear()
# Do some stuff
print('Stuff!')
print('Successfully exited while loop!')
return
if __name__ == '__main__':
# Initialising events
stop_event = Event()
new_image_event = Event()
# Starting the thread
thread = Thread(target=stream_data, args=(stop_event, new_image_event, ))
thread.start()
# Do stuff before setting the stop event, while generating a 'new' new_image_event every 1s
for i in range(5):
new_image_event.set()
time.sleep(1)
# generating the stop event
stop_event.set()
print('stop_event has been set')
# joining back the thread
thread.join()Output:
Stuff! Stuff! Stuff! Stuff! Stuff! stop_event has been set
So the new_image_event does it's job, and at the end the stop_event is successfully set. But for some reason this does not break the while loop in the thread, and 'Successfully exited while loop!' is never printed. Why? And how can I solve this (preferably without resorting to classes and/or self)?