
- Python 基礎
- Python - 首頁
- Python - 概述
- Python - 歷史
- Python - 特性
- Python vs C++
- Python - Hello World 程式
- Python - 應用領域
- Python - 直譯器
- Python - 環境搭建
- Python - 虛擬環境
- Python - 基本語法
- Python - 變數
- Python - 資料型別
- Python - 型別轉換
- Python - Unicode 系統
- Python - 字面量
- Python - 運算子
- Python - 算術運算子
- Python - 比較運算子
- Python - 賦值運算子
- Python - 邏輯運算子
- Python - 位運算子
- Python - 成員運算子
- Python - 身份運算子
- Python - 運算子優先順序
- Python - 註釋
- Python - 使用者輸入
- Python - 數字
- Python - 布林值
- Python 控制語句
- Python - 控制流
- Python - 決策
- Python - if 語句
- Python - if else
- Python - 巢狀 if
- Python - match-case 語句
- Python - 迴圈
- Python - for 迴圈
- Python - for-else 迴圈
- Python - while 迴圈
- Python - break 語句
- Python - continue 語句
- Python - pass 語句
- Python - 巢狀迴圈
- Python 函式與模組
- Python - 函式
- Python - 預設引數
- Python - 關鍵字引數
- Python - 僅限關鍵字引數
- Python - 位置引數
- Python - 僅限位置引數
- Python - 可變引數
- Python - 變數作用域
- Python - 函式註解
- Python - 模組
- Python - 內建函式
- Python 字串
- Python - 字串
- Python - 字串切片
- Python - 修改字串
- Python - 字串連線
- Python - 字串格式化
- Python - 跳脫字元
- Python - 字串方法
- Python - 字串練習
- Python 列表
- Python - 列表
- Python - 訪問列表元素
- Python - 修改列表元素
- Python - 新增列表元素
- Python - 刪除列表元素
- Python - 迴圈遍歷列表
- Python - 列表推導式
- Python - 排序列表
- Python - 複製列表
- Python - 合併列表
- Python - 列表方法
- Python - 列表練習
- Python 元組
- Python - 元組
- Python - 訪問元組元素
- Python - 更新元組
- Python - 解包元組
- Python - 迴圈遍歷元組
- Python - 合併元組
- Python - 元組方法
- Python - 元組練習
- Python 集合
- Python - 集合
- Python - 訪問集合元素
- Python - 新增集合元素
- Python - 刪除集合元素
- Python - 迴圈遍歷集合
- Python - 合併集合
- Python - 複製集合
- Python - 集合運算子
- Python - 集合方法
- Python - 集合練習
- Python 字典
- Python - 字典
- Python - 訪問字典元素
- Python - 修改字典元素
- Python - 新增字典元素
- Python - 刪除字典元素
- Python - 字典檢視物件
- Python - 迴圈遍歷字典
- Python - 複製字典
- Python - 巢狀字典
- Python - 字典方法
- Python - 字典練習
- Python 陣列
- Python - 陣列
- Python - 訪問陣列元素
- Python - 新增陣列元素
- Python - 刪除陣列元素
- Python - 迴圈遍歷陣列
- Python - 複製陣列
- Python - 反轉陣列
- Python - 排序陣列
- Python - 合併陣列
- Python - 陣列方法
- Python - 陣列練習
- Python 檔案處理
- Python - 檔案處理
- Python - 寫入檔案
- Python - 讀取檔案
- Python - 重新命名和刪除檔案
- Python - 目錄
- Python - 檔案方法
- Python - OS 檔案/目錄方法
- Python - OS 路徑方法
- 面向物件程式設計
- Python - OOPs 概念
- Python - 類與物件
- Python - 類屬性
- Python - 類方法
- Python - 靜態方法
- Python - 建構函式
- Python - 訪問修飾符
- Python - 繼承
- Python - 多型
- Python - 方法重寫
- Python - 方法過載
- Python - 動態繫結
- Python - 動態型別
- Python - 抽象
- Python - 封裝
- Python - 介面
- Python - 包
- Python - 內部類
- Python - 匿名類和物件
- Python - 單例類
- Python - 包裝類
- Python - 列舉
- Python - 反射
- Python 錯誤與異常
- Python - 語法錯誤
- Python - 異常
- Python - try-except 塊
- Python - try-finally 塊
- Python - 丟擲異常
- Python - 異常鏈
- Python - 巢狀 try 塊
- Python - 使用者自定義異常
- Python - 日誌記錄
- Python - 斷言
- Python - 內建異常
- Python 多執行緒
- Python - 多執行緒
- Python - 執行緒生命週期
- Python - 建立執行緒
- Python - 啟動執行緒
- Python - 等待執行緒結束
- Python - 執行緒命名
- Python - 執行緒排程
- Python - 執行緒池
- Python - 主執行緒
- Python - 執行緒優先順序
- Python - 守護執行緒
- Python - 執行緒同步
- Python 同步
- Python - 執行緒間通訊
- Python - 執行緒死鎖
- Python - 中斷執行緒
- Python 網路程式設計
- Python - 網路程式設計
- Python - 套接字程式設計
- Python - URL 處理
- Python - 泛型
- Python 庫
- NumPy 教程
- Pandas 教程
- SciPy 教程
- Matplotlib 教程
- Django 教程
- OpenCV 教程
- Python 雜項
- Python - 日期與時間
- Python - 數學
- Python - 迭代器
- Python - 生成器
- Python - 閉包
- Python - 裝飾器
- Python - 遞迴
- Python - 正則表示式
- Python - PIP
- Python - 資料庫訪問
- Python - 弱引用
- Python - 序列化
- Python - 模板
- Python - 輸出格式化
- Python - 效能測量
- Python - 資料壓縮
- Python - CGI 程式設計
- Python - XML 處理
- Python - GUI 程式設計
- Python - 命令列引數
- Python - 文件字串
- Python - JSON
- Python - 傳送郵件
- Python - 擴充套件
- Python - 工具/實用程式
- Python - GUIs
- Python 高階概念
- Python - 抽象基類
- Python - 自定義異常
- Python - 高階函式
- Python - 物件內部機制
- Python - 記憶體管理
- Python - 元類
- Python - 使用元類進行超程式設計
- Python - 模擬和樁
- Python - Monkey Patching
- Python - 訊號處理
- Python - 型別提示
- Python - 自動化教程
- Python - Humanize 包
- Python - 上下文管理器
- Python - 協程
- Python - 描述符
- Python - 診斷和修復記憶體洩漏
- Python - 不可變資料結構
- Python 有用資源
- Python - 問答
- Python - 線上測試
- Python - 快速指南
- Python - 參考
- Python - 速查表
- Python - 專案
- Python - 有用資源
- Python - 討論
- Python 編譯器
- NumPy 編譯器
- Matplotlib 編譯器
- SciPy 編譯器
Python - 執行緒間通訊
執行緒間通訊是指在 Python 多執行緒程式中啟用執行緒之間通訊和同步的過程。
通常,Python 中的執行緒共享程序中的同一記憶體空間,這允許它們透過共享變數、物件和threading模組提供的專用同步機制來交換資料並協調其活動。
為了促進執行緒間通訊,threading 模組提供了各種同步原語,例如鎖、事件、條件和訊號量物件。在本教程中,您將學習如何使用 Event 和 Condition 物件在多執行緒程式中實現執行緒間的通訊。
Event 物件
Event 物件管理內部標誌的狀態,以便執行緒可以等待或設定。Event物件提供控制此標誌狀態的方法,允許執行緒基於共享條件同步其活動。
該標誌最初為假,使用 set() 方法設定為真,使用 clear() 方法重置為假。wait() 方法會阻塞,直到標誌為真。
以下是Event物件的關鍵方法:
- is_set():當且僅當內部標誌為真時返回 True。
- set():將內部標誌設定為真。所有等待它變為真的執行緒都會被喚醒。一旦標誌為真,呼叫 wait() 的執行緒根本不會阻塞。
- clear():將內部標誌重置為假。隨後,呼叫 wait() 的執行緒將阻塞,直到呼叫 set() 將內部標誌再次設定為真。
- wait(timeout=None):阻塞直到內部標誌為真。如果在進入時內部標誌為真,則立即返回。否則,阻塞直到另一個執行緒呼叫 set() 將標誌設定為真,或直到可選超時發生。當存在 timeout 引數且不為 None 時,它應該是一個浮點數,以秒為單位指定操作的超時時間。
示例
以下程式碼嘗試模擬由交通訊號燈狀態(綠色或紅色)控制的交通流量。
程式中有兩個執行緒,它們分別針對兩個不同的函式。signal_state() 函式定期設定和重置事件,表示訊號從綠色變為紅色。
traffic_flow() 函式等待事件被設定,並在事件保持設定狀態時執行迴圈。
from threading import Event, Thread import time terminate = False def signal_state(): global terminate while not terminate: time.sleep(0.5) print("Traffic Police Giving GREEN Signal") event.set() time.sleep(1) print("Traffic Police Giving RED Signal") event.clear() def traffic_flow(): global terminate num = 0 while num < 10 and not terminate: print("Waiting for GREEN Signal") event.wait() print("GREEN Signal ... Traffic can move") while event.is_set() and not terminate: num += 1 print("Vehicle No:", num," Crossing the Signal") time.sleep(1) print("RED Signal ... Traffic has to wait") event = Event() t1 = Thread(target=signal_state) t2 = Thread(target=traffic_flow) t1.start() t2.start() # Terminate the threads after some time time.sleep(5) terminate = True # join all threads to complete t1.join() t2.join() print("Exiting Main Thread")
輸出
執行上述程式碼後,您將獲得以下輸出:
Waiting for GREEN Signal Traffic Police Giving GREEN Signal GREEN Signal ... Traffic can move Vehicle No: 1 Crossing the Signal Traffic Police Giving RED Signal RED Signal ... Traffic has to wait Waiting for GREEN Signal Traffic Police Giving GREEN Signal GREEN Signal ... Traffic can move Vehicle No: 2 Crossing the Signal Vehicle No: 3 Crossing the Signal Traffic Police Giving RED Signal Traffic Police Giving GREEN Signal Vehicle No: 4 Crossing the Signal Traffic Police Giving RED Signal RED Signal ... Traffic has to wait Traffic Police Giving GREEN Signal Traffic Police Giving RED Signal Exiting Main Thread
Condition 物件
Python 的threading模組中的 Condition 物件提供了一種更高階的同步機制。它允許執行緒在繼續執行之前等待來自另一個執行緒的通知。Condition 物件始終與鎖相關聯,並提供執行緒間訊號機制。
以下是 threading.Condition() 類的語法:
threading.Condition(lock=None)
以下是 Condition 物件的關鍵方法:
- acquire(*args):獲取底層鎖。此方法呼叫底層鎖上的相應方法;返回值是該方法返回的任何內容。
- release():釋放底層鎖。此方法呼叫底層鎖上的相應方法;沒有返回值。
- wait(timeout=None): 此方法釋放底層鎖,然後阻塞,直到另一個執行緒對同一個條件變數呼叫 notify() 或 notify_all() 方法喚醒它,或者直到可選的超時發生。一旦被喚醒或超時,它會重新獲取鎖並返回。
- wait_for(predicate, timeout=None): 此實用程式方法可能會重複呼叫 wait(),直到滿足謂詞或發生超時。返回值是謂詞的最後返回值,如果方法超時則將評估為 False。
- notify(n=1): 此方法最多喚醒 n 個等待條件變數的執行緒;如果沒有任何執行緒正在等待,則此方法什麼也不做。
- notify_all(): 喚醒所有等待此條件的執行緒。此方法類似於 notify(),但它會喚醒所有等待執行緒,而不是一個執行緒。如果呼叫執行緒在呼叫此方法時未獲取鎖,則會引發 RuntimeError。
示例
此示例演示了使用 Python threading 模組的 Condition 物件進行執行緒間通訊的一種簡單形式。這裡 thread_a 和 thread_b 使用 Condition 物件進行通訊,thread_a 等待直到收到來自 thread_b 的通知。thread_b 休眠 2 秒後通知 thread_a,然後結束。
from threading import Condition, Thread import time c = Condition() def thread_a(): print("Thread A started") with c: print("Thread A waiting for permission...") c.wait() print("Thread A got permission!") print("Thread A finished") def thread_b(): print("Thread B started") with c: time.sleep(2) print("Notifying Thread A...") c.notify() print("Thread B finished") Thread(target=thread_a).start() Thread(target=thread_b).start()
輸出
執行上述程式碼後,您將獲得以下輸出:
Thread A started Thread A waiting for permission... Thread B started Notifying Thread A... Thread B finished Thread A got permission! Thread A finished
示例
這是另一個程式碼示例,演示瞭如何使用 Condition 物件線上程之間進行通訊。在這個例子中,執行緒 t2 執行 taskB() 函式,執行緒 t1 執行 taskA() 函式。t1 執行緒獲取條件併發出通知。
此時,t2 執行緒處於等待狀態。條件釋放後,等待執行緒繼續使用通知函式生成的隨機數。
from threading import Condition, Thread import time import random numbers = [] def taskA(c): for _ in range(5): with c: num = random.randint(1, 10) print("Generated random number:", num) numbers.append(num) print("Notification issued") c.notify() time.sleep(0.3) def taskB(c): for i in range(5): with c: print("waiting for update") while not numbers: c.wait() print("Obtained random number", numbers.pop()) time.sleep(0.3) c = Condition() t1 = Thread(target=taskB, args=(c,)) t2 = Thread(target=taskA, args=(c,)) t1.start() t2.start() t1.join() t2.join() print("Done")
執行此程式碼時,將產生以下輸出:
waiting for update Generated random number: 2 Notification issued Obtained random number 2 Generated random number: 5 Notification issued waiting for update Obtained random number 5 Generated random number: 1 Notification issued waiting for update Obtained random number 1 Generated random number: 9 Notification issued waiting for update Obtained random number 9 Generated random number: 2 Notification issued waiting for update Obtained random number 2 Done