Python threading event objects 溝通範例教學

Last updated on  Jul 24, 2023  in  Python 程式設計 - 中階  by  Amo Chen  ‐ 2 min read

The simplest mechanisms for communication between threads: one thread signals an event and other threads wait for it.

Threads(執行緒)之間溝通最簡單的方式,即是透過 Event Objects ,這種方式通常應用在 1 個 thread 發起 1 個 event ,然後其他 threads 會等待發出 event 的 thread ,譬如 1 個發號施令的 thread ,其他 threads 會等待該 thread 發號施令後才開始工作。

以下範例程式模擬 1 個 BOSS 及 2 個 WORKER , WORKER 會在 BOSS 的號令下才開始工作,最後 BOSS 喊休息時才結束。

# -*- encoding: utf-8 -*-
import threading

from time import sleep
from random import choice


def boss(event):
    print('[B] I am boss, I am ready')
    sleep(5)

    print('[B] All workers, work now')
    event.set()
    sleep(20)

    print('[B] All workers, take a break now')
    event.clear()


def worker(event, worker_name):
    print('[W] I am worker', worker_name, ', I am waiting for the boss')
    event_is_set = event.wait()

    while event.is_set():
        color = choice(['red', 'black', 'green'])
        print('[W]', worker_name, 'choices', color)
        sleep(5)


event = threading.Event()

boss_thread = threading.Thread(name='boss', target=boss, args=(event, ))
worker_thread_1 = threading.Thread(name='worker-john', target=worker, args=(event, 'John'))
worker_thread_2 = threading.Thread(name='worker-kate', target=worker, args=(event, 'Kate'))

boss_thread.start()
worker_thread_1.start()
worker_thread_2.start()

執行後會出現以下結果:

[B] I am boss, I am ready
[W] I am worker John , I am waiting for the boss
[W] I am worker Kate , I am waiting for the boss
[B] All workers, work now
[W] John choices red
[W] Kate choices green
[W] John choices red
[W] Kate choices red
[W] John choices green
[W] Kate choices green
[W] Kate choices green
[W] John choices green
[B] All workers, take a break now

可以看到 WORKER 都在 BOSS 發號施令後才開始工作,這就是 Event Objects 最簡單的範例。

接著開始詳細解說上述範例:

首先, event = threading.Event() 創造了 1 個 Event Object ,然後我們分別創造 1 個 BOSS thread 及 2 個 WORKER threads 。這 2 種 thread 都共同接受 1 個 event 當作參數,而這個 event 就是我們創造的 Event Object ,如此一來,我們才能在 boss 及 worker 2 個函數中透過共同的 Event Object 溝通。

boss 函數所做的事情不多,主要就是利用 event.set() 將 Event Object 內部的 flag 設定為 True ,最後再透過 event.clear() 將 Event Object 內部的 flag 設定回 False

An event manages a flag that can be set to true with the set() method and reset to false with the clear() method.

而 worker 函數稍微有趣一點,在函數一開始 event.wait() 就會 block 住,等待 Event Object 內部的 flag 設定為 True ,所以在 boss 函數尚未呼叫 set() 之前, worker 函數會一直卡在 event.wait() 那一行,直到 boss 呼叫 event.set() 之後,就會進入 while 迴圈開始工作,直到 event.is_set() 回傳 False 為止。

以上就是 Event Objects 的介紹,詳細可以參閱 Python 官方文件。

References

https://docs.python.org/3/library/threading.html#event-objects

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!