什么是Condtion?

所谓condition条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据。 这种同步机制就是一个线程等待特定的条件,另一个线程通知它条件已经发生。一旦条件发生,该线程就会获取锁,从而独占共享资源的访问。 Condition包含以下部分:

  • c.acquire(*args):获取底层锁。此方法将调用底层锁上对应的acquire(*args)方法。
  • c.release():释放底层锁。此方法将调用底层锁上对应的release()方法
  • c.wait(timeout):等待直到获取通知或出现超时为止。此方法在调用线程已经获取锁之后调用。 调用时,将释放底层锁,而且线程将进入睡眠状态,直到另一个线程在条件变量上执行notify()notify_all()方法将其唤醒为止。在线程被唤醒后,线程讲重新获取锁,方法也会返回。timeout是浮点数,单位为秒。 如果超时,线程将被唤醒,重新获取锁,而控制将被返回。
  • c.notify(n):唤醒一个或多个等待此条件变量的线程。此方法只会在调用线程已经获取锁之后调用, 而且如果没有正在等待的线程,它就什么也不做。 n指定要唤醒的线程数量,默认为1.被唤醒的线程在它们重新获取锁之前不会从wait()调用返回。
  • c.notify_all():唤醒所有等待此条件的线程。

通俗的解释:

Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则 wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复 这一过程,从而解决复杂的同步问题。 可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对 象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify 方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。 Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。

带有缓冲区的生产者-消费者模型

我们可以根据所谓的wait池构建一个带有缓冲区的生产者-消费者模型,即缓冲区好比一个仓库,生产者可以不断生产商品知道仓库装满,然后告知消费者消费,而消费者也可以判断仓库是否满了从而告知生产者继续生产商品:


import threading
import time# 假设商品数量
goods = 0condition = threading.Condition()def consumer():global goodswhile True:condition.acquire()if goods <= 0:# 仓库空了,即特定条件满足了,通知生产者生产condition.notify()condition.wait()time.sleep(2)goods -= 1print('consume 1, left {}'.format(goods))time.sleep(2)condition.release()def producer():global goodswhile True:condition.acquire()if goods >= 5:# 仓库满了,即特定条件满足了,通知消费者消费condition.notify()condition.wait()time.sleep(2)goods += 1print('produce 1, already {}'.format(goods))time.sleep(2)condition.release()if __name__ == '__main__':thread_consumer = threading.Thread(target=consumer)thread_producer = threading.Thread(target=producer)thread_consumer.start()thread_producer.start()thread_consumer.join()thread_producer.join()print('consumer-producer example end.')复制代码

运行截图如下:

转载于:https://juejin.im/post/5caf4298e51d456e442ff2fa

Python并行编程(四):多线程同步之condition(条件变量)实现带有缓冲区的生产者-消费者模型...相关推荐

  1. linux网络编程之posix 线程(四):posix 条件变量与互斥锁 示例生产者--消费者问题

    http://blog.csdn.net/jnu_simba/article/details/9129939 一.posix 条件变量 一种线程间同步的情形:线程A需要等某个条件成立才能继续往下执行, ...

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

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

  3. Linux多线程——生产者消费者模型

    目录 一.生产者消费者模型 1.1 什么是生成者消费者模型 1.2 生产者消费者模型的优点 1.3 基于阻塞队列实现生产者消费者模型 1.4 POSIX信号量 1.4.1 信号量概念 1.4.2 P操 ...

  4. Python 并行编程教程 | Lynda教程 中文字幕

    Python 并行编程教程 | Lynda教程 中文字幕 Python Parallel Programming Solutions 课程ID: 604237 时长: 4.0小时 所属类别:Pytho ...

  5. python并行编程篇

    章节目录 第二十一章 进程对象 进程的理解 操作系统 OS发展史 第二十二章 进程并发 进程并发的原理 进程并发编程实践 僵尸进程与孤儿进程(linux系统) 守护进程 互斥锁 IPC机制(进程间的通 ...

  6. 【Java 并发编程】多线程、线程同步、死锁、线程间通信(生产者消费者模型)、可重入锁、线程池

    并发编程(Concurrent Programming) 进程(Process).线程(Thread).线程的串行 多线程 多线程的原理 多线程的优缺点 Java并发编程 默认线程 开启新线程 `Ru ...

  7. python并发编程之多线程

    多线程 线程 1.什么是线程 进程是一个执行空间 , 线程就是其中真正工作的单位 , 每一个进程至少有一个线程(如果我们把操作系统比喻为一个工厂 , 进程就是车间 , 线程就是流水线) 进程包含了运行 ...

  8. Linux 多线程编程(实现生产者消费者模型)

    Linux 多线程编程 线程分类 线程按照其调度者可以分为用户级线程和内核级线程两种. 内核级线程 在一个系统上实现线程模型的方式有好几种,因内核和用户空间提供的支持而有一定程度的级别差异.最简单的模 ...

  9. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

最新文章

  1. Java实现算法导论中求解模线性方程解(基于最大公约数欧几里得扩展算法)
  2. centos启动流程
  3. 获取Ip所在城市名与详细
  4. Waymo冰火两重天:无人出租车最快今秋推出,高管团队嫌隙严重
  5. 利用 pywin32 操作 excel
  6. .Net 内存对象分析
  7. 使用HazelCast进行休眠缓存:JPA缓存基础知识
  8. Eclipse中的codetemplates.xml
  9. [转载] python的 for、while循环、嵌套循环
  10. 新建pch文件及配置
  11. 【Shiro第一篇】 Shiro权限框架简介
  12. android电视机清理内存,电视盒子总是内存不足?五大清理方法释放更多内存
  13. 开源的网页防篡改监控工具推荐——WGCLOUD
  14. ppt计算机实验报告册,PPT实验报告册
  15. Frequent values RMQ
  16. Linux、Windows、Mac非root普通用户使用秘钥免密SSH登录
  17. 如何用scanf语句为字符指针数组赋值
  18. 全网首发?蚂蚁金服内部共享—1658页《Java面试突击核心讲》
  19. Python工具箱系列(七)
  20. java 排队_实验排队功能实现(JAVA)

热门文章

  1. 简单数据结构——单向链表
  2. 手机锁屏密码忘记了怎么办,清除锁屏的办法
  3. 机器学习算法中的过拟合与欠拟合(转载)
  4. Java中的Random()函数 【转载】
  5. OpenResty(nginx)操作mysql的初步应用
  6. 造轮子,常用JS处理HTML工具(HTMLUtils)
  7. 升级到只读域控制器RODC
  8. 将含有自定义代码的Infopath模板发布到Sharepoint表单库中
  9. VS2010用Winform编写 Excel程序
  10. 在Linux下安装LaTeX+CJK+中文字体的方法 [转]