1. 缓冲区(此处用阻塞队列充当),解决消费者和生产者强耦合问题。(生产者和消费者不直接通信)

2. 通过平衡生产者线程和消费者线程,来提高程序整体处理数据速度。

3. 在并发编程中该模式能解决大多数并发问题。


4. 例子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()

5. 例子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()

最新文章

  1. <c:if test="value ne, eq, lt, gt,...."> 用法
  2. web系统架构设计中需要知道的点(前端篇)
  3. UE4 在C++ 动态生成几何、BSP体、Brush ---- Mesh_Generation
  4. netbeans环境的建立
  5. java中的URL InetAddress类
  6. [转载] gitbook安装与使用
  7. Vue中实现一个无限加载列表
  8. [二十三]JavaIO之PushbackReader
  9. python爬虫scrapy项目详解(关注、持续更新)
  10. 学习Docker之Dockerfile的命令
  11. miniprogrampatch 提供 watch 和 computed 特性
  12. select和select的数据渲染,你知道多少呢?
  13. iOS - 身份证判断正则加算法
  14. mysql相关SQL
  15. 如何使用putty远程连接linux
  16. PHP+Gtk实例(求24点)
  17. swift3.0通过响应链获取当前试图的控制器
  18. 搭建coreseek(sphinx+mmseg3)详细安装配置+php之sphinx扩展安装+php调用示例(转)
  19. iOS 可能用到的三方框架
  20. [GO]new函数的使用

热门文章

  1. Linux - 命令 - 查找命令总结
  2. MSYS2与mingw32和mingw64的安装
  3. springboot笔记-2-.核心的上下文以及配置扫描解析(上)
  4. 【 SSH 实例】使用ssh开发的简单项目
  5. Python turtle库详解
  6. jq的 on 事件委托 导致多次执行问题
  7. queue的使用-Hdu 1702
  8. SQLite - C/C++接口 API(二)
  9. JIT对锁的优化- 锁消除和锁粗化案例分析
  10. 【Go语言系列】1.3、GO语言简介:Go语言开发的知名项目