Python並行編程(六):多線程同步之queue(隊列)實現生產者-消費者模型

方便的隊列

當咱們處理多線程的資源共享時,線程模塊的管理會變得很複雜。咱們已經看到了,Python線程模塊提供了不少同步原語,包括鎖、信號量、條件變量、事件等。雖然有這麼多的選擇,可是使用隊列可能會是管理線程同步的最佳拍檔。隊列使用起來很容易,由於該模塊提供了同步的,安全的對序列,包括FIFO(先入先出)隊列Queue,LIFO(後入先出)隊列LifoQueue,和優先級隊列PriorityQueue.這些隊列都實現了鎖原語,可以在多線程中直接使用。可使用隊列來實現線程間的通訊: Queue模塊中的經常使用方法:python

  • Queue.qsize():返回隊列的大小
  • Queue.empty():若是隊列爲空,返回True,反之False
  • Queue.full():若是隊列滿了,返回True,反之False
  • Queue.full:與 maxsize 大小對應
  • Queue.get([block[, timeout]]):獲取隊列,timeout等待時間
  • Queue.get_nowait() :至關Queue.get(False)
  • Queue.put(item):寫入隊列,timeout等待時間
  • Queue.put_nowait(item):至關Queue.put(item, False)
  • Queue.task_done():在完成一項工做以後,Queue.task_done()函數向任務已經完成的隊列發送一個信號
  • Queue.join():實際上意味着等到隊列爲空,再執行別的操做

生產者-消費者模型

利用隊列實現生產者-消費者模型:安全

import threading
import queue
import random
import time

# 建立一個隊列
q = queue.Queue()

# 假定商品序號
item = 0


def produecr():
    global item
    while True:
        time.sleep(1)
        item = random.randint(1, 10)
        # 將一個「商品」推到隊列中
        q.put(item)
        print('producer {}th gooos append to q.'.format(item))
        time.sleep(1)


def consumer():
    while True:
        # 在隊列中刪除一個「商品」,並返回該「商品」
        item = q.get()
        print(threading.currentThread().getName() +
              'consumer get {}th goods from q.'.format(item))
        q.task_done()


if __name__ == "__main__":
    threads_consumr = []
    for i in range(3):
        t = threading.Thread(target=consumer)
        t.start()
        threads_consumr .append(t)

    thread_producer = threading.Thread(target=produecr)
    thread_producer.start()
    q.join()
    for t in threads_consumr:
        t.join()
    thread_producer.join()

複製代碼

運行截圖以下: 多線程

運行結果
咱們能夠看到隊列的使用適用於這種常常發生的場景:好比當有成千上萬那的數據亟待處理,而後每次取出一條數據進行處理,如何利用多線程分配處理任務加快處理效率呢? 咱們能夠將數據進行分割而後交給多個線程去跑,但是這並非一個明智的作法。在這裏咱們可使用隊列與線程相結合的方式進行任務分配。 能夠利用隊列線程的思想: 首先建立一個全局共享的隊列,隊列中只存在有限個元素,並將全部的數據逐條加入到隊列中,並調用隊列的join函數進行等待。以後即可以開啓若干線程,線程的任務就是不斷的從隊列中取數據進行處理就能夠了。
相關文章
相關標籤/搜索