1. 程式人生 > >操作系統OS,Python - 生產者消費者模型

操作系統OS,Python - 生產者消費者模型

UC lease 整體 left 多個 eas 資源 解決 臨界區

1. 緩沖區(此處用阻塞隊列充當),解決消費者和生產者強耦合問題。(生產者和消費者不直接通信)

2. 通過平衡生產者線程和消費者線程,來提高程序整體處理數據速度。

3. 在並發編程中該模式能解決大多數並發問題。

例子1. 生產者生產一次,每個消費者消費一次

import threading
import queue
import time
 
def producer():
    for i in range(10):
        q.put("餃子 %s" % i )
 
    print("開始等待所有的餃子被取走...")
    #把操作隊列的線程join到生產者線程,待這些線程結束後,生產者線程再往下執行。
q.join() print("所有的餃子被取完了...") def consumer(n): while q.qsize() >0: print("%s 取到" %n , q.get()) q.task_done() time.sleep(1) q = queue.Queue() p1 = threading.Thread(target=producer,) p1.start() p2 = threading.Thread(target=consumer, args=(‘Allen1‘
,)) p2.start() p3 = threading.Thread(target=consumer, args=(‘Allen2‘,)) p3.start()

例子2. 生產者和消費者動態生成或者消費

知識點:

  1. 臨界區(加鎖解鎖)
  2. 緩沖區(本例為阻塞隊列)
  3. 生產者,消費者同步
import time,random
import queue,threading

#緩沖區用阻塞隊列實現
q = queue.Queue()
#臨界區指的是一個訪問共用資源(例如:共用設備或是共用存儲器)的程序片段,而這些共用資源又無法同時被多個線程訪問的特性
#生成全局鎖,對緩沖區這個共享資源(臨界資源)進行加鎖解鎖操作
lock = threading.Lock() def Producer(name): """ 生產者在0-3秒內動態生產餃子 """ count = 1 global lock while True: time.sleep(random.randrange(3)) #生產者線程進入臨界區 #修改緩沖區前加鎖 lock.acquire() #緩沖區滿,生產者線程阻塞,雖然此處的緩沖區(隊列)沒有設置maxsize q.put(count, block=True) print(‘Producer %s produced 1 jiaozi, has produced %s jiaozi...%i jiaozi left‘ %(name, count, q.qsize())) count +=1 lock.release() #生產者線程退出臨界區 def Consumer(name): """ 消費者在0-4秒內動態消費餃子 """ count = 1 global lock while True: time.sleep(random.randrange(4)) #消費者線程進入臨界區 lock.acquire() if not q.empty(): #緩沖區為空,消費者線程阻塞,雖然此處的緩沖區(隊列)沒有設置maxsize q.get(block=True) print(\033[32;1mConsumer %s took 1 jiaozi, has taken %s jiaozi...%i jiaozi left\033[0m‘ %(name, count, q.qsize())) count += 1 lock.release() #消費者線程退出臨界區 if __name__ == ‘__main__‘: p1 = threading.Thread(target=Producer, args=(‘p1‘,)) p2 = threading.Thread(target=Producer, args=(‘p2‘,)) c1 = threading.Thread(target=Consumer, args=(‘c1‘,)) c2 = threading.Thread(target=Consumer, args=(‘c2‘,)) p1.start() p2.start() c1.start() c2.start()

操作系統OS,Python - 生產者消費者模型