不废话,直接上四种模式,为方便大家复制,直接贴出代码

1、条件变量(Condition)方式,最复杂的一种

# 条件变量(Condition):锁功能加入等待和唤醒功能,默认RLock# 两个线程用一个 cond 锁,手动唤醒和等待import timefrom threading import Threadfrom threading import Conditioncond = Condition()  # 两个线程共享一个锁num = 0def producer():  # 生产者线程    global num    with cond:        while True:            num += 1            print('生产1个,总数:{}'.format(num))            if num == 3:                print('已达到3个,不再生产')                time.sleep(3)                cond.notify()  # 循环 3 次,唤醒消费者线程                cond.wait()  # 释放锁,挂起生产者线程def customer():  # 消费者线程    global num    with cond:        while True:            num -= 1            print('消费了1个,剩余:{}'.format(num))            if num == 0:                print('已消费3个,唤醒生产者')                time.sleep(3)                cond.notify()  # 唤醒生产者线程                cond.wait()  # 释放锁,挂起消费者线程thd1 = Thread(target=producer)thd2 = Thread(target=customer)thd1.start()thd2.start()thd1.join()  # 线程同步-等子线程结束,主线程再继续运行thd2.join()  # 线程同步-等子线程结束,主线程再继续运行# 条件变量(Condition)的返回:# 连续返回:"""生产1个,总数:1生产1个,总数:2生产1个,总数:3已达到3个,不再生产消费了1个,剩余:2消费了1个,剩余:1消费了1个,剩余:0已消费3个,唤醒生产者......"""
# 解释一下上面程序:"""1、定义一个锁 con = Condition(),这个锁在两个线程中共享,只能一个线程运行2、先启动 thd1.start(),再启动 thd2.start()3、生产者线程先获得con锁,消费者线程遇到con锁,只能等待4、生产者在 con 锁内,循环3次,满足 if num == 3: 的条件5、用 con.notify() 唤醒其他线程(消费者线程)6、用 con.wait() 释放锁,并挂起当前线程(生产者线程)7、消费者线程 获得 con 锁,循环 3 次,满足 if num == 0: 的条件8、用 con.notify() 唤醒其他线程(生产者线程)9、用 con.wait() 释放锁,并挂起当前线程(消费者线程)再进行 4、5、6、7、8、9 步骤,反复用一个锁控制线程的唤醒和挂起"""

2、消息队列(queue)模式

# 生产者、消费者模型(边生产,边消费)from threading import Threadimport queuedef producter(que):    num = 0    while num < 3:        num += 1        que.put(num)        print('生产{}'.format(num))def customer(que):    while True:        data = que.get()        print('消费{}'.format(data))que = queue.Queue()t1 = Thread(target=producter,args=(que,))t2 = Thread(target=customer,args=(que,))t1.start()t2.start()# 打印返回:以下打印不一定按照顺序来的"""生产1生产2消费1生产3消费2消费3"""

3、协成方式(yield)

# 协程函数# 接收数据并处理def customer():    while True:        n = yield  # 接收生产者消息        print('消费:{}'.format(n))# 发送给生成器数据def producer(c):    c.send(None)  # 第一次启动生成器必须发送None,等价于 r = next(c)    for i in range(1,3):        print('生产:{}'.format(i))  # 生成器外部 接收生成器 多次返回出来的值        r = c.send(i)c = customer()producer(c)  # 两个函数产生关系。把生成器作为参数传入# 打印返回:"""生产:1消费:1生产:2消费:2"""

主线程 唤醒_python线程之九:生产者消费者3种方式,2个线程1个协程相关推荐

  1. 【Linux入门】多线程(线程概念、生产者消费者模型、消息队列、线程池)万字解说

    目录 1️⃣线程概念 什么是线程 线程的优点 线程的缺点 线程异常 线程异常 Linux进程VS线程 2️⃣线程控制 创建线程 获取线程的id 线程终止 等待线程 线程分离 3️⃣线程互斥 进程线程间 ...

  2. 生产者消费者模型实现方式:管程法,信号灯法

    管程法 生产者:负责生产的数据模块 消费者:负责处理数据的模块 缓冲区:消费者不能直接从生产者获取产品,生产者生产进入缓冲区 public class Demo {public static void ...

  3. java callable接口_Java多线程之Callable接口的实现有返回值的线程

    import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util. ...

  4. QT线程之 moveToThread() 只能用信号槽方式触发

    qt的线程使用方法有把某个对象的函数放置线程里执行,方法为moveToThread() 具体操作步骤为: 1.创建一个新的类,让这个类从 QObject 派生 class MyWork:public ...

  5. python 遍历字符串的每一个字符_Python之字符串的遍历的4种方式

    python的字符串遍历有4种方式: 1. 下标法 2. for in 3. iter内置函数 4. enumerate 其中下标法和enumerate适合需要判断后续字符的场景,比如循环到下标ind ...

  6. .net session 有效时间_Python中requests模拟登录的三种方式(携带cookie/session进行请求网站)...

    这篇文章主要介绍了python中requests模拟登录的三种方式(携带cookie/session进行请求网站),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋 ...

  7. python 当前文件路径获取方式_python中获取文件路径的几种方式

    # 如果执行文件为E:\aa\bb\aa.py 1.获取当前路径 current_path11 = os.path.abspath(__file__) current_path12 = os.path ...

  8. python读取音频文件_python 读取wav 音频文件的两种方式

    JavaScript算法(冒泡排序.选择排序与插入排序) 冒泡排序.选择排序与插入排序复杂度都是二次方级别的,放在一起说吧. 介绍一些学习这三个排序方法的比较好的资料.冒泡排序看介绍的冒泡排序,选择排 ...

  9. python爬虫有几种方法_python爬虫-----Python访问http的几种方式

    爬取页面数据,我们需要访问页面,发送http请求,以下内容就是Python发送请求的几种简单方式: 会使用到的库 urllib requests 1.urlopen import urllib.req ...

最新文章

  1. html标签article,html标签中section与article 区别
  2. NSTimer循环引用的问题
  3. apache php 升级5.6,升级 apache2.4.41-php5.6.40
  4. 内核中的 likely() 与 unlikely()
  5. 如何预防后台被攻击?Tomcat 的安全配置来啦!
  6. redistemplate 设置永不过期_解决密码已过期,拒绝访问问题
  7. 调研分析:全球与中国汽车后置摄像头模组市场现状及未来发展趋势
  8. 各个浏览器的详细信息
  9. 怎样将生成的pdf文件转为eps文件
  10. 在ubuntu下用sublime text3编译C++和pascal
  11. Pygame实战:还在玩纸飞机?不—现在家里的小孩子都在玩儿飞机大冒险~
  12. Android流媒体播放器
  13. 笔记44-JQuery高级笔记
  14. Lodash源码解析-------chunk函数
  15. 【蓝桥杯省赛真题2】Scratch射击螃蟹 少儿编程scratch蓝桥杯选拔赛真题讲解
  16. GDUT_排位赛题解报告_第3场_B.Loan Repayment
  17. 用音响里的零件做迷你小机器人_用这些磁性“积木”,搭个迷你机器人|这个设计了不起...
  18. Android ndk 编译出现'Build Project' has encountered a problem.Errors occurred during the build
  19. 无效的列类型: 1111
  20. macOS 安装istats zsh: command not found: istats

热门文章

  1. 如何查看其他人的ABAP authorization check log
  2. BW report execution callstack
  3. SAP CRM里使用BAdI阻止产品主数据保存的一种办法
  4. 如何在SAP云平台上使用MongoDB服务 1
  5. java python混合开发_Go+Python双语言混合开发
  6. python大数据运维库_大数据集群运维(10)Pycharm下安装模块
  7. 如何在redhat8里使用gcc命令_如何使用DISM命令行工具修复Windows 10映像
  8. 解决Springboot文件上传报错,java.io.FileNotFoundException: D:\System\Temp\tomcat.819...00.tmp (系统找不到指定的文件。)
  9. php mysql连续签到跨月_PHP连续签到功能实现方法详解
  10. dw字体红色阴影_DW网页制作,傻瓜级教学来了!