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