双队列+多线程 模拟 生产者-消费者模式

生产者-消费者简单理解:生产者相当于厨师,消费者相当于顾客,容器相当于出餐窗口,或者相当与放餐的一个东西。但是这个东西放餐的位置是有顺序的。而厨师跟消费生产与用餐是没有顺序的。kakfa这种是有多个容器的发布订阅模式。

python 可以与redis, Rabbitmq,kafka 等实现生产者消费者模式,但是python还可以使用队列实现生产者与消费者模型。

1、首先了解Queue(队列)的数据结构形式,队列一般用排队的方式进行比喻,画一下队列的示意图。先进先出, python的Queue是怎样做此功能的呢?    也是一样的。

 2、生产者容器队列消费者三者关系图,图形如下。

 

 4、首先创建第一个队列Q1,用来模拟多线程生产者要 生产的数据, 创建1000个数字 0-999,放入队列中。其次再次创建一个队列Q2,这个用来模拟redis或者rabbitmq的订阅模式的容器,来存放生产者生产的数据,与消费者要消费的数据。

import queue
from threading import Thread

Q1 = queue.Queue()
for i in range(1000):
	Q1.put(i)
Q2 = queue.Queue()

 5、创建生产者Producer,这里可以使用多线程,继承多线程的方式

class Product(Thread):
	
	def __init__(self, Queue):
		super(Product, self).__init__()
		self.queue = Queue # 这个Queue是Q2
		
	def general_data(self):
		data = Q1.get()
		self.queue.put(data)
		print(f'name: {threading.current_thread().name} 生成一条数据',data)
	
	def run(self):
		while True:
			if self.cli.qsize() > 10000:
				break
			else:
				self.general_data()
		print(f'name: {threading.current_thread().name} is over!!!')
        
if __name__ == '__main__':
	thread_list= []
	for i in range(3):
		producer = Product(Q2)
		thread_list.append(producer)
		producer.start()
	# 阻塞生产者线程
	for t in thread_list:
		t.join()

 打印结果:

6、创建消费者,消费者的代码跟生产者的代码差不多,因为都是多线程多线程

class Consumer(Thread):
   
   def __init__(self, Queue):
      super(Consumer, self).__init__()
      self.queue = Queue
   
   def get_data(self):
      data = self.queue.get()
      if data is None:
         return None
      else:
         print(f'name: {threading.current_thread().name} 消费1条数据', number)
   
   def run(self):
      while True:
         self.get_data()
         if self.queue.qsize() == 0:
            break
      print(f'name: {threading.current_thread().name} 消费完了!!!')
  
if __name__ == '__main__':
	for i in range(3):
		consumer = Consumer(Q2)
		consumer.start()

打印结果:

 注意点:使用队列也是可以进行生产者与消费者模式进行模拟的,只不过,出与数据的安全问题,一般不适用队列Queue,一般使用redis,rabbitmq,这些中间,因为这些中间件是可以将数据进行持久化的,来保证数据的安全。也是因为,生产者与消费者一般是两个进程进行执行的,又因为进程是无法进行通信的,线程之间是可以进行通讯的,所以可以用队列来在一个模块中模拟。如果将生产者与消费者写到两者文件中,是没办法进行模拟的,自己动手可以试一下。

(该事例生产者,消费者代码是在一个文件中)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值