1. 程式人生 > >Python並行程式設計(九):執行緒通訊queue

Python並行程式設計(九):執行緒通訊queue

1、基本概念

      當執行緒之間要共享資源或資料的時候,可能變的非常複雜。Python的threading模組提供了很多同步原語,包括訊號量,條件變數,事件和鎖。如果可以使用這些原語的話,應該優先考慮使用這些,而不是使用queue模組。佇列操作起來更容易,也使多執行緒程式設計更安全,因為佇列可以將資源的使用通過單執行緒進行完全控制,並且允許使用更加整潔和可讀性更高的設計模式。

      Queue常用的方法有以下四個:

            - put():往queue中放一個item

            - get():從queue刪除一個item,並返回刪除的這個item

            - task_done():每次item被處理的時候需要呼叫這個方法

            - join():所以item在被處理之前一直阻塞

2、程式碼示例

from threading import Thread, Event
from queue import Queue
import time
import random
class producer(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    def run(self):
        for i in range(10):
            item 
= random.randint(0, 256) self.queue.put(item) print('Producer notify:item %d appended to queue by %s' %(item, self.name)) time.sleep(1) class consumer(Thread): def __init__(self, queue): Thread.__init__(self) self.queue = queue def run(self):
while True: item = self.queue.get() print('Consumer notify: %d popped from queue by %s' %(item, self.name)) if __name__ == "__main__": queue = Queue() t1 = producer(queue) t2 = consumer(queue) t3 = consumer(queue) t4 = consumer(queue) t1.start() t2.start() t3.start() t4.start() t1.join() t2.join() t3.join() t4.join()

      生產者使用Queue.put(item [,block[, timeout]])往queue中插入資料,Queue是同步的,在插入資料之前內部有一個內建的鎖機制。

      可能發生的兩種情況:

            - 如果block為True,timeout為None(預設),那麼可能會阻塞掉,直到出現可用的位置。如果timeout是正整數,那麼阻塞直到這個時間,就會丟擲一個異常。

            - 如果block為False,如果佇列有閒置那麼會立即插入,否則就立即丟擲異常(timeout將會被忽略),本例中,put()檢查佇列是否已滿,然後呼叫wait()開始等待。

      消費者從佇列中取出整數然後用task_done()方法將其標位任務已處理。

      消費者使用Queue.get([block[, timeout]])從佇列中取回資料,queue內部也會經過鎖的處理。如果佇列為空,消費者阻塞。

3、流程圖