Python threading模块condition原理及运行流程详解


Posted in Python onOctober 05, 2020

Condition的处理流程如下:

首先acquire一个条件变量,然后判断一些条件。

  • 如果条件不满足则wait;
  • 如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。
  • 不断的重复这一过程,从而解决复杂的同步问题。

Condition的基本原理如下:

可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。

Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。

除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有的线程永远处于沉默状态。

演示条件变量同步的经典问题是生产者与消费者问题:假设有一群生产者(Producer)和一群消费者(Consumer)通过一个市场来交互产品。生产者的”策略“是如果市场上剩余的产品少于1000个,那么就生产100个产品放到市场上;而消费者的”策略“是如果市场上剩余产品的数量多余100个,那么就消费3个产品。用Condition解决生产者与消费者问题的代码如下:

# -*- coding: utf-8 -*-
"""
Created on Wed Nov 28 17:15:29 2018

@author: 18665
"""

import threading
import time

class Producer(threading.Thread):
  # 生产者函数
  def run(self):
    global count
    while True:
      if con.acquire():
        # 当count 小于等于1000 的时候进行生产
        if count > 1000:
          con.wait()
        else:
          count = count+100
          msg = self.name+' produce 100, count=' + str(count)
          print(msg)
          # 完成生成后唤醒waiting状态的线程,
          # 从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁
          con.notify()
        con.release()
        time.sleep(1)

class Consumer(threading.Thread):
  # 消费者函数
  def run(self):
    global count
    while True:
      # 当count 大于等于100的时候进行消费
      if con.acquire():
        if count < 100:
          con.wait()
        
        else:
          count = count-5
          msg = self.name+' consume 5, count='+str(count)
          print(msg)
          con.notify()
          # 完成生成后唤醒waiting状态的线程,
          # 从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁
        con.release()
        time.sleep(1)

count = 500
con = threading.Condition()

def test():
  for i in range(2):
    p = Producer()
    p.start()
  for i in range(5):
    c = Consumer()
    c.start()
if __name__ == '__main__':
  test()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
栈和队列数据结构的基本概念及其相关的Python实现
Aug 24 Python
Python的标准模块包json详解
Mar 13 Python
Python将DataFrame的某一列作为index的方法
Apr 08 Python
对Python中9种生成新对象的方法总结
May 23 Python
Python3匿名函数用法示例
Jul 25 Python
详解python中Numpy的属性与创建矩阵
Sep 10 Python
python得到电脑的开机时间方法
Oct 15 Python
Pyqt清空某一个QTreeewidgetItem下的所有分支方法
Jun 17 Python
python 哈希表实现简单python字典代码实例
Sep 27 Python
安装Pycharm2019以及配置anconda教程的方法步骤
Nov 11 Python
python状态机transitions库详解
Jun 02 Python
Python Numpy库的超详细教程
Apr 06 Python
Python urllib库如何添加headers过程解析
Oct 05 #Python
Python3获取cookie常用三种方案
Oct 05 #Python
Python collections.deque双边队列原理详解
Oct 05 #Python
Python全局变量与global关键字常见错误解决方案
Oct 05 #Python
Python定时任务框架APScheduler原理及常用代码
Oct 05 #Python
Python xmltodict模块安装及代码实例
Oct 05 #Python
Python pathlib模块使用方法及实例解析
Oct 05 #Python
You might like
PHP之将POST数据转化为字符串的实现代码
2016/11/03 PHP
js实现的网站首页随机公告随机公告
2007/03/14 Javascript
input 高级限制级用法
2009/03/26 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
2013/12/05 Javascript
parentElement,srcElement的使用小结
2014/01/13 Javascript
jquery动态更换设置背景图的方法
2014/03/25 Javascript
Javascript中获取对象的原型对象的方法小结
2015/02/25 Javascript
使用jquery提交form表单并自定义action的方法
2016/05/25 Javascript
阿里云ecs服务器中安装部署node.js的步骤
2016/10/08 Javascript
js实现的xml对象转json功能示例
2016/12/24 Javascript
判断颜色是否合法的正则表达式(详解)
2017/05/03 Javascript
xmlplus组件设计系列之下拉刷新(PullRefresh)(6)
2017/05/03 Javascript
jQuery实现锚点向下平滑滚动特效示例
2017/08/29 jQuery
jQuery获取所有父级元素及同级元素及子元素的方法(推荐)
2018/01/21 jQuery
解决在vue项目中,发版之后,背景图片报错,路径不对的问题
2018/03/06 Javascript
ES6 Proxy实现Vue的变化检测问题
2019/06/11 Javascript
8 个有用的JS技巧(推荐)
2019/07/03 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
微信小程序中使用 async/await的方法实例分析
2020/05/06 Javascript
Linux 下 Python 实现按任意键退出的实现方法
2016/09/25 Python
详解python如何在django中为用户模型添加自定义权限
2018/10/15 Python
Python发送邮件功能示例【使用QQ邮箱】
2018/12/04 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
2018/12/06 Python
Python命名空间的本质和加载顺序
2018/12/17 Python
Win10 安装PyCharm2019.1.1(图文教程)
2019/09/29 Python
Python远程开发环境部署与调试过程图解
2019/12/09 Python
HTML5实现经典坦克大战坦克乱走还能发出一个子弹
2013/09/02 HTML / CSS
迟到检讨书500字
2014/02/05 职场文书
党校学习心得体会范文
2014/09/09 职场文书
居委会四风问题个人对照检查材料
2014/09/25 职场文书
销售2014年度工作总结
2014/12/08 职场文书
团员个人年度总结
2015/02/26 职场文书
Python打包为exe详细教程
2021/05/18 Python
Python实现简单得递归下降Parser
2022/05/02 Python
源码安装apache脚本部署过程详解
2022/09/23 Servers