一、什么是生產者消費者模型?
生產者和消費者問題是線程模型中的經典問題:生產者和消費者在同一時間段內共用同一個存儲空間,生產者往存儲空間中添加數據,消費者從存儲空間中取走數據,當存儲空間為空時,消費者阻塞,當存儲空間滿時,生產者阻塞。
二、為什么要使用生產者和消費者模式?
生產者線程用於生產數據,另一種是消費者線程用於消費數據,為了解耦生產者和消費者的關系(不用一直等待對方的數據)。
通常會采用共享的數據區域,就像是一個倉庫,生產者生產數據之后直接放置在共享數據區中,並不需要關心消費者的行為;而消費者只需要從共享數據區中去獲取數據,就不再需要關心生產者的行為。
三、python 代碼示例
1、通過queue隊列實現:
模型:
生產者線程持續生產,最多生產兩個,滿兩個后阻塞,消費者線程每2s 消費一個,消費后生產者線程繼續生產直到再次滿兩個阻塞,
假設消費者消費快於 生產者生產,則消費者阻塞
假設消費者消費慢於 生產者生產,則生產者阻塞
''' 通過隊列實現生產者消費者模型 ''' import threading,queue,time # 創建一個隊列,隊列最大長度為2 q = queue.Queue(maxsize=2) def product(): while True: # 生產者往隊列塞數據 q.put('money') print('生產時間',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) print('生產了') def consume(): while True: time.sleep(2) # 消費者取出數據 data = q.get() print('消費時間',time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) print('消費了%s'%data) t = threading.Thread(target=product) t1 = threading.Thread(target=consume) t.start() t1.start()
2、通過 線程鎖 Condition 實現
模型:
生產者生產一個,通知消費者消費
消費者消費完畢,通知生產者再造一個
'''通過條件鎖實現生產者消費者模型''' import threading,time,datetime # 生產者 lock = threading.Condition() something = None def product(): global something while True: print('生產者的something=',something) while something ==None: print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) time.sleep(5) #生產money 需要5s lock.acquire() something = 'money' print('我生產了money') lock.notify() #生產完成后立即通知消費者 消費 print('生產者通知消費者已經生產') lock.wait() #生產者生產完畢后,里層while循環 終止,線程進入外層循環,在wait 處 掛起 ,等待消費者通知 def consumer(): global something while True: print('消費者的something=',something) lock.acquire() # 需要先加鎖后面 才能wait() while something=='money': something = None # 消費將 something置為 none 里層的while循環 中止 , print('money被我消費了') # time.sleep(2) lock.notify() print('消費者通知生產者已經消費') print('等待通知') lock.wait() #里層 while 循環結束后,線程執行至wait掛起 等待生產者 生產 后通 p = threading.Thread(target=product) c = threading.Thread(target=consumer) p.start() c.start()