Python 實現生產者消費者模式

生產者消費者模型

 

 

生產者消費者模式,即多條消費者線程和多條生產者線程共用同一緩衝區,線程之間協調工作。簡單來說,生產者將信息發送至緩衝區,消費者將緩衝區的數據取出並進行處理。

 

生產者消費者模式的實現

流程圖:

生產者線程產生隨機數(信息),將其放入隊列,而消費者線程將隊列中的數據取出,進行處理。

代碼

main.py

import producer
import consumer
import threading
import queue

#初始化
q_data=queue.Queue(maxsize=1000)
event=threading.Event()
lock=threading.Lock()

if event.isSet:
	event.clear()
	

for each in range(5):
	c=consumer.Consumer(each,q_data,event,lock,5000)
	p=producer.Producer(each,q_data,event,5000)
	c.start()
	p.start()
	
q_data.join()

producer.py

import threading
import random

class Producer(threading.Thread):
	def __init__(self,name,queue,event,num):
		threading.Thread.__init__(self)
		self.name="生產者"+str(name)
		self.queue=queue
		self.event=event
		self.num=num
		self.count=0

		
	def run(self):
		while self.count<self.num:
			#判斷棧是否已經滿
			if self.queue.full():
				#棧滿 線程進入等待
				self.event.wait()
				#線程喚醒後將flag設置爲False
				if self.event.isSet():
					self.event.clear()
			else:
				#判斷棧是否爲空,爲空則在向棧添加數據後,則將Flag設置爲True,
				#喚醒前所有在等待的消費者線程
				if self.queue.empty():
					#未滿 向棧添加數據
					data=random.randint(0,5000)
					self.queue.put(data)
					print(self.name+" produced data "+ str(data))
					#將Flag設置爲True
					self.event.set()
				else:
					#未滿 向棧添加數據
					data=random.randint(0,5000)
					self.queue.put(data)
					print(self.name+" produced data "+ str(data))
		
			self.count+=1

consumer.py

import threading

class Consumer(threading.Thread):
	def __init__(self,name,queue,event,lock,num):
		threading.Thread.__init__(self)
		self.name="消費者"+str(name)
		self.queue=queue
		self.event=event
		self.lock=lock
		self.num=num
		self.count=0
		
	def run(self):
		while self.count<self.num:
			#判斷棧是否爲空
			if self.queue.empty():
				#棧空 線程進入等待
				self.event.wait()
				#線程喚醒後將flag設置爲False
				if self.event.isSet():
					self.event.clear()
			else:
				#判斷棧是否已滿,爲滿則在向棧取數據後,則將Flag設置爲True,
				#喚醒前所有在等待的生產者線程
				if self.queue.full():
					#未滿 向棧添加數據
					self.lock.acquire()
					data=self.queue.get()
					self.queue.task_done()
					self.lock.release()
					print(self.name+" Spend data "+ str(data))
					#將Flag設置爲True
					self.event.set()
				else:
					#未滿 向棧添加數據
					self.lock.acquire()
					data=self.queue.get()
					self.queue.task_done()
					self.lock.release()
					print(self.name+" Spend data "+ str(data))
			
			self.count+=1

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章