執行緒程式設計 同步佇列

2021-08-21 09:43:07 字數 1328 閱讀 1303

我們經常會採用生產者/消費者關係的兩個執行緒來處理乙個共享緩衝區的資料。例如一 個生產者執行緒接受使用者資料放入乙個共享緩衝區裡,等待乙個消費者執行緒對資料取出處理。但是如果緩衝區的太小而生產者和消費者兩個非同步執行緒的速度不同時,容 易出現乙個執行緒等待另乙個情況。為了盡可能的縮短共享資源並以相同速度工作的各執行緒的等待時間,我們可以使用乙個「佇列」來提供額外的緩衝區。

建立乙個「佇列」物件

import queue 

myqueue = queue.queue(maxsize = 10)queue.queue類即是乙個佇列的同步實現。佇列長度可為無限或者有限。可通過queue的建構函式的可選引數maxsize來設定佇列長度。如果maxsize小於1就表示佇列長度無限。

將乙個值放入佇列中

myqueue.put(10)呼叫佇列物件的put()方法在隊尾插入乙個專案。put()有兩個引數,第乙個item為必需的,為插入專案的值;第二個block為可選引數, 預設為1。如果佇列當前為空且block為1,put()方法就使呼叫執行緒暫停,直到空出乙個資料單元。如果block為0,put方法將引發full異 常。

將乙個值從佇列中取出

myqueue.get()呼叫佇列物件的get()方法從隊頭刪除並返回乙個專案。可選引數為block,預設為1。如果隊列為空且block為1,get()就使呼叫執行緒暫停,直至有專案可用。如果block為0,佇列將引發empty異常。

我們用乙個例子來展示如何使用queue

在 python 中使用執行緒時,這個模式是一種很常見的並且推薦使用的方式。具體工作步驟描述如下:

建立乙個 queue.queue() 的例項,然後使用資料對它進行填充。 

將經過填充資料的例項傳遞給執行緒類,後者是通過繼承 threading.thread 的方式建立的。 

生成守護執行緒池。 

每次從佇列中取出乙個專案,並使用該執行緒中的資料和 run 方法以執行相應的工作。 

在完成這項工作之後,使用 queue.task_done() 函式向任務已經完成的佇列傳送乙個訊號。 

對佇列執行 join 操作,實際上意味著等到隊列為空,再退出主程式。 

在使用這個模式時需要注意一點:通過將守護執行緒設定為 true,將允許主線程或者程式僅在守護執行緒處於活動狀態時才能夠退出。這種方式建立了一種簡單的方式以控制程式流程,因為在退出之前,您可以對佇列執行 join 操作、或者等到隊列為空。

join()

保持阻塞狀態,直到處理了佇列中的所有專案為止。在將乙個專案新增到該佇列時,未完成的任務的總數就會增加。當使用者執行緒呼叫 task_done() 以表示檢索了該專案、並完成了所有的工作時,那麼未完成的任務的總數就會減少。當未完成的任務的總數減少到零時,join() 就會結束阻塞狀態。

多執行緒和同步佇列

最近要割接個專案,要把另外乙個公司的資料庫裡的一張表倒到我們庫里,資料有一億三千多萬吧。正號也符合生產者和消費者的狀況。以前用過點執行緒池和同步佇列,寫個例子,讓大家拍磚。不多說了,直接上 1.執行緒池 public class threadpool override public void run...

CLH同步佇列

aqs內部維護著乙個fifo佇列,該佇列就是clh同步佇列。clh同步佇列是乙個fifo雙向佇列,aqs依賴它來完成同步狀態的管理,當前執行緒如果獲取同步狀態失敗時,aqs則會將當前執行緒已經等待狀態等資訊構造成乙個節點 node 並將其加入到clh同步佇列,同時會阻塞當前執行緒,當同步狀態釋放時,...

(原創)C 同步佇列

同步佇列作為乙個執行緒安全的資料共享區,經常用於執行緒之間資料讀取,比如半同步半非同步執行緒池的同步佇列。其實做起來比較簡單,要用到list 鎖和條件變數,條件變數的作用是在佇列滿了或者空了的時候等待通知。先看乙個簡單的同步佇列 include include include include inc...