1. 程式人生 > >Python-執行緒-佇列-阻塞佇列解耦合

Python-執行緒-佇列-阻塞佇列解耦合

# encoding=utf-8

import threading
import time

try:  # python2中
    from Queue import Queue
except ModuleNotFoundError:  # python3中
    from queue import Queue

"""
Python的Queue模組中提供了同步的、執行緒安全的佇列類,
    包括FIFO(先入先出)佇列Queue,LIFO(後入先出)佇列LifoQueue,和優先順序佇列PriorityQueue。
    這些佇列都實現了鎖原語(可以理解為原子操作,即要麼不做,要麼就做完),能夠在多執行緒中直接使用。
    可以使用佇列來實現執行緒間的同步。
Queue使用
    對於Queue,在多執行緒通訊之間扮演重要的角色
    新增資料到佇列中,使用put()方法
    從佇列中取資料,使用get()方法
    判斷佇列中是否還有資料,使用qsize()方法
為什麼要使用生產者和消費者模式
    線上程世界裡,生產者就是生產資料的執行緒,消費者就是消費資料的執行緒。
    在多執行緒開發當中,如果生產者處理速度很快,而消費者處理速度很慢,那麼生產者就必須等待消費者處理完,才能繼續生產資料。
    同樣的道理,如果消費者的處理能力大於生產者,那麼消費者就必須等待生產者。
    為了解決這個問題於是引入了生產者和消費者模式。
什麼是生產者消費者模式
    生產者消費者模式是通過一個容器來解決生產者和消費者的強耦合問題。
    生產者和消費者彼此之間不直接通訊,而通過阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費者處理,
    直接扔給阻塞佇列,消費者不找生產者要資料,而是直接從阻塞佇列裡取,阻塞佇列就相當於一個緩衝區,
    平衡了生產者和消費者的處理能力。
    這個阻塞佇列就是用來給生產者和消費者解耦的。縱觀大多數設計模式,都會找一個第三者出來進行解耦,
用FIFO佇列實現生產者與消費者問題的程式碼如下:
"""


class Producer(threading.Thread):
    def run(self):
        global queue
        count = 0
        while True:
            if queue.qsize() < 1000:
                for i in range(100):
                    count = count + 1
                    msg = '生成產品' + str(count)
                    queue.put(msg)
                    print(msg)
            time.sleep(0.5)


class Consumer(threading.Thread):
    def run(self):
        global queue
        while True:
            if queue.qsize() > 100:
                for i in range(3):
                    msg = self.name + '消費了 ' + queue.get()
                    print(msg)
            time.sleep(1)


if __name__ == '__main__':
    queue = Queue()

    for i in range(500):
        queue.put('初始產品' + str(i))
    for i in range(2):
        p = Producer()
        p.start()
    for i in range(5):
        c = Consumer()
        c.start()