Summary: in this tutorial, you’ll learn how to use the Python threading Event object to communicate between threads.
Introduction to the Python threading Event object
Sometimes, you need to communicate between the threads. To do that, you can use a lock (mutex) and a boolean variable.
However, Python provides you with a better way to communicate between threads using the Event
class from the threading
module.
The Event
class offers a simple but effective way to coordinate between threads: one thread signals an event while other threads wait for it.
The Event
object wraps a boolean flag that can be set (True
) or cleared (False
). Multiple threads can wait for an Event
to be set before proceeding or can reset the Event
back to the cleared state.
The following illustrates the steps for using the Event
object:
First, import the Event
from the threading
module:
from threading import Event
Code language: Python (python)
Next, create a new Event
object:
event = Event()
Code language: Python (python)
By default, the event is not set (cleared). The is_set()
method of the event object will return False
:
if event.is_set():
# ...
Code language: Python (python)
Then, set an event using the set()
method:
event.set()
Code language: Python (python)
Once an event is set, all the threads that wait on the event will be notified automatically.
After that, unset an event via the clear()
method:
event.clear()
Code language: Python (python)
Finally, threads can wait for the event to be set via the wait()
method:
event.wait()
Code language: Python (python)
The wait()
method blocks the execution of a thread until the event is set. In other words, the wait()
method will block the current thread until another thread call the set()
method to set the event.
If an event is set, the wait()
function returns immediately.
To specify how long the thread is going to wait, you can use the timeout argument. For example:
event.wait(timeout=5) # wait for 5 seconds
Code language: Python (python)
Python threading event example
The following example shows a simple example of using the Event
object to communicate between threads:
from threading import Thread, Event
from time import sleep
def task(event: Event, id: int) -> None:
print(f'Thread {id} started. Waiting for the signal....')
event.wait()
print(f'Received signal. The thread {id} was completed.')
def main() -> None:
event = Event()
t1 = Thread(target=task, args=(event,1))
t2 = Thread(target=task, args=(event,2))
t1.start()
t2.start()
print('Blocking the main thread for 3 seconds...')
sleep(3)
event.set()
if __name__ == '__main__':
main()
Code language: Python (python)
Output:
Thread 1 started. Waiting for the signal....
Thread 2 started. Waiting for the signal....
Blocking the main thread for 3 seconds...
Received signal. The thread 1 was completed.
Received signal. The thread 2 was completed.
Code language: Python (python)
How it works.
First, define the task()
function that accepts an Event
object and an integer:
def task(event: Event, id: int) -> None:
print(f'Thread {id} started. Wait for the signal....')
event.wait()
print(f'Receive signal. The thread {id} was completed.')
Code language: Python (python)
Inside, the task()
function, we call the wait()
method of the event object to wait for the event to be set by the main thread.
Second, create an Event
object inside the main()
function:
event = Event()
Code language: Python (python)
Third, create two child threads that execute the task()
function with the same event object and different id 1 and 2:
t1 = Thread(target=task, args=(event,1))
t2 = Thread(target=task, args=(event,2))
Code language: Python (python)
Fourth, start both threads by calling the start()
method:
t1.start()
t2.start()
Code language: Python (python)
Fifth, call the sleep()
method to block the main thread for three seconds:
sleep(3)
Code language: Python (python)
Since the task()
function call the wait()
method of the event object, both t1
and t2
threads will wait for the event to be set before continuing.
Finally, set the event by calling the set()
method from the main thread:
event.set()
Code language: Python (python)
Both t1
and t2
threads will be notified and continue executing until the end.
Note that you’ll learn how to use the Event object to stop a child thread from the main thread in the next tutorial.
Practical example of using Threading event
The following example illustrates hwo to use the threading event to synchronize between two threads:
- Thread #1 downloads a text file from URL
https://www.ietf.org/rfc/rfc793.txt
, once completed, it notifies the second thread to count the words from the downloaded text file. - Thread #2 starts and wait for the completed signal from the thread #1. Once, receiving the signal, it starts counting the words from the downloaded file.
Here’s the complete program:
from threading import Thread, Event
from urllib import request
def download_file(url, event):
# Download the file form URL
print(f"Downloading file from {url}...")
filename, _ = request.urlretrieve(url, "rfc793.txt")
# File download completed, set the event
event.set()
def process_file(event):
print("Waiting for the file to be downloaded...")
event.wait() # Wait for the event to be set
# File has been downloaded, start processing it
print("File download completed. Starting file processing...")
# Count the number of words in the file
word_count = 0
with open("rfc793.txt", "r") as file:
for line in file:
words = line.split()
word_count += len(words)
# Print the word count
print(f"Number of words in the file: {word_count}")
def main():
# Create an Event object
event = Event()
# Create and start the file download thread
download_thread = Thread(target=download_file,
args=("https://www.ietf.org/rfc/rfc793.txt", event))
download_thread.start()
# Create and start the file processing thread
process_thread = Thread(target=process_file, args=(event,))
process_thread.start()
# Wait for both threads to complete
download_thread.join()
process_thread.join()
print("Main thread finished.")
if __name__ == '__main__' :
main()
Code language: PHP (php)
Summary
- Use the
threading.Event
class to communicate between threads. - Use the
set()
method to set the event andclear()
method to unset the event. - Use the
is_set()
method to check if an event is set. - Use the
wait()
method to wait for the event to be set.