{"id":307,"date":"2024-01-28T10:38:40","date_gmt":"2024-01-28T10:38:40","guid":{"rendered":"https:\/\/learnpython.elegantwallp.com\/?p=307"},"modified":"2024-01-28T10:38:41","modified_gmt":"2024-01-28T10:38:41","slug":"python-threading-event","status":"publish","type":"post","link":"https:\/\/learnpython.elegantwallp.com\/2024\/01\/28\/python-threading-event\/","title":{"rendered":"Python Threading Event"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you\u2019ll learn how to use the Python threading Event object to communicate between threads.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction to the Python threading Event object<\/h2>\n\n\n\n<p>Sometimes, you need to communicate between the\u00a0threads. To do that, you can use a\u00a0lock\u00a0(mutex) and a boolean variable.<\/p>\n\n\n\n<p>However, Python provides you with a better way to communicate between threads using the&nbsp;<code>Event<\/code>&nbsp;class from the&nbsp;<code>threading<\/code>&nbsp;module.<\/p>\n\n\n\n<p>The&nbsp;<code>Event<\/code>&nbsp;class offers a simple but effective way to coordinate between threads: one thread signals an event while other threads wait for it.<\/p>\n\n\n\n<p>The&nbsp;<code>Event<\/code>&nbsp;object wraps a boolean flag that can be set (<code>True<\/code>) or cleared (<code>False<\/code>). Multiple threads can wait for an&nbsp;<code>Event<\/code>&nbsp;to be set before proceeding or can reset the&nbsp;<code>Event<\/code>&nbsp;back to the cleared state.<\/p>\n\n\n\n<p>The following illustrates the steps for using the&nbsp;<code>Event<\/code>&nbsp;object:<\/p>\n\n\n\n<p>First, import the\u00a0<code>Event<\/code>\u00a0from the\u00a0<code>threading<\/code>\u00a0module:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>from threading import Event<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Next, create a new\u00a0<code>Event<\/code>\u00a0object:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event = Event()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>By default, the event is not set (cleared). The\u00a0<code>is_set()<\/code>\u00a0method of the event object will return\u00a0<code>False<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>if event.is_set(): <em># ...<\/em><\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Then, set an event using the\u00a0<code>set()<\/code>\u00a0method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event.set()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Once an event is set, all the threads that wait on the event will be notified automatically.<\/p>\n\n\n\n<p>After that, unset an event via the\u00a0<code>clear()<\/code>\u00a0method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event.clear()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Finally, threads can wait for the event to be set via the\u00a0<code>wait()<\/code>\u00a0method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event.wait()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>wait()<\/code>&nbsp;method blocks the execution of a thread until the event is set. In other words, the&nbsp;<code>wait()<\/code>&nbsp;method will block the current thread until another thread call the&nbsp;<code>set()<\/code>&nbsp;method to set the event.<\/p>\n\n\n\n<p>If an event is set, the&nbsp;<code>wait()<\/code>&nbsp;function returns immediately.<\/p>\n\n\n\n<p>To specify how long the thread is going to wait, you can use the timeout argument. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event.wait(timeout=5) <em># wait for 5 seconds<\/em><\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Python threading event example<\/h2>\n\n\n\n<p>The following example shows a simple example of using the\u00a0<code>Event<\/code>\u00a0object to communicate between threads:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>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><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>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><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>How it works.<\/p>\n\n\n\n<p>First, define the\u00a0<code>task()<\/code>\u00a0function that accepts an\u00a0<code>Event<\/code>\u00a0object and an integer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>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><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Inside, the&nbsp;<code>task()<\/code>&nbsp;function, we call the&nbsp;<code>wait()<\/code>&nbsp;method of the event object to wait for the event to be set by the main thread.<\/p>\n\n\n\n<p>Second, create an\u00a0<code>Event<\/code>\u00a0object inside the\u00a0<code>main()<\/code>\u00a0function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event = Event()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Third, create two child threads that execute the\u00a0<code>task()<\/code>\u00a0function with the same event object and different id 1 and 2:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>t1 = Thread(target=task, args=(event,1)) t2 = Thread(target=task, args=(event,2))<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Fourth, start both threads by calling the\u00a0<code>start()<\/code>\u00a0method:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>t1.start() t2.start()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Fifth, call the\u00a0<code>sleep()<\/code>\u00a0method to block the main thread for three seconds:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>sleep(3)<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Since the&nbsp;<code>task()<\/code>&nbsp;function call the&nbsp;<code>wait()<\/code>&nbsp;method of the event object, both&nbsp;<code>t1<\/code>&nbsp;and&nbsp;<code>t2<\/code>&nbsp;threads will wait for the event to be set before continuing.<\/p>\n\n\n\n<p>Finally, set the event by calling the\u00a0<code>set()<\/code>\u00a0method from the main thread:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>event.set()<\/code><small>Code language: Python (python)<\/small><\/code><\/pre>\n\n\n\n<p>Both&nbsp;<code>t1<\/code>&nbsp;and&nbsp;<code>t2<\/code>&nbsp;threads will be notified and continue executing until the end.<\/p>\n\n\n\n<p>Note that you\u2019ll learn how to use the Event object to\u00a0stop a child thread\u00a0from the main thread in the next tutorial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Practical example of using Threading event<\/h2>\n\n\n\n<p>The following example illustrates hwo to use the threading event to synchronize between two threads:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Thread #1 downloads a text file from URL&nbsp;<code>https:\/\/www.ietf.org\/rfc\/rfc793.txt<\/code>, once completed, it notifies the second thread to count the words from the downloaded text file.<\/li>\n\n\n\n<li>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.<\/li>\n<\/ul>\n\n\n\n<p>Here\u2019s the complete program:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><code>from threading import Thread, Event from urllib import request def download_file(url, event): <em># Download the file form URL<\/em> print(f\"Downloading file from {url}...\") filename, _ = request.urlretrieve(url, \"rfc793.txt\") <em># File download completed, set the event<\/em> event.set() def process_file(event): print(\"Waiting for the file to be downloaded...\") event.wait() <em># Wait for the event to be set<\/em> <em># File has been downloaded, start processing it<\/em> print(\"File download completed. Starting file processing...\") <em># Count the number of words in the file<\/em> word_count = 0 with open(\"rfc793.txt\", \"r\") as file: for line in file: words = line.split() word_count += len(words) <em># Print the word count<\/em> print(f\"Number of words in the file: {word_count}\") def main(): <em># Create an Event object<\/em> event = Event() <em># Create and start the file download thread<\/em> download_thread = Thread(target=download_file, args=(\"https:\/\/www.ietf.org\/rfc\/rfc793.txt\", event)) download_thread.start() <em># Create and start the file processing thread<\/em> process_thread = Thread(target=process_file, args=(event,)) process_thread.start() <em># Wait for both threads to complete<\/em> download_thread.join() process_thread.join() print(\"Main thread finished.\") if __name__ == '__main__' : main()<\/code><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Summary: in this tutorial, you\u2019ll 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\u00a0threads. To do that, you can use a\u00a0lock\u00a0(mutex) and a boolean variable. However, Python provides you with a better way to communicate between threads [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[],"class_list":["post-307","post","type-post","status-publish","format-standard","hentry","category-1-python-concurrency"],"_links":{"self":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/307","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/comments?post=307"}],"version-history":[{"count":1,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/307\/revisions"}],"predecessor-version":[{"id":308,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/posts\/307\/revisions\/308"}],"wp:attachment":[{"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/media?parent=307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/categories?post=307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnpython.elegantwallp.com\/wp-json\/wp\/v2\/tags?post=307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}