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 相关文章推荐
Django中使用locals()函数的技巧
Jul 16 Python
python爬虫入门教程--HTML文本的解析库BeautifulSoup(四)
May 25 Python
关于Python中浮点数精度处理的技巧总结
Aug 10 Python
Tensorflow 合并通道及加载子模型的方法
Jul 26 Python
pygame游戏之旅 python和pygame安装教程
Nov 20 Python
python钉钉机器人运维脚本监控实例
Feb 20 Python
50行Python代码实现视频中物体颜色识别和跟踪(必须以红色为例)
Nov 20 Python
python Django 反向访问器的外键冲突解决
May 20 Python
Python lambda表达式原理及用法解析
Aug 18 Python
python爬虫分布式获取数据的实例方法
Nov 26 Python
pytorch训练神经网络爆内存的解决方案
May 22 Python
Python 数据可视化之Seaborn详解
Nov 02 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
ob_start(),ob_start('ob_gzhandler')使用
2006/12/25 PHP
一道求$b相对于$a的相对路径的php代码
2010/08/08 PHP
php循环语句 for()与foreach()用法区别介绍
2012/09/05 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
2016/06/30 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
jQuery实战之品牌展示列表效果
2011/04/10 Javascript
jQuery代码优化 选择符篇
2011/11/01 Javascript
jqTransform form表单美化插件使用方法
2012/07/05 Javascript
getComputedStyle与currentStyle获取样式(style/class)
2013/03/19 Javascript
学习JavaScript设计模式之单例模式
2016/01/19 Javascript
AngularJS实现表单验证功能详解
2017/10/12 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
利用ECharts.js画K线图的方法示例
2018/01/10 Javascript
React Navigation 使用中遇到的问题小结
2018/05/08 Javascript
浅谈Vue路由快照实现思路及其问题
2018/06/07 Javascript
简述JS浏览器的三种弹窗
2018/07/15 Javascript
微信小程序引入Vant组件库过程解析
2019/08/06 Javascript
适合前端Vue开发童鞋的跨平台Weex的使用详解
2019/10/16 Javascript
微信小程序开发(二):页面跳转并传参操作示例
2020/06/01 Javascript
[05:20]2018DOTA2亚洲邀请赛主赛事第三日战况回顾 LGD率先挺进胜者组决赛
2018/04/06 DOTA
Python实现测试磁盘性能的方法
2015/03/12 Python
Python字符串格式化输出方法分析
2016/04/13 Python
Python面向对象之静态属性、类方法与静态方法分析
2018/08/24 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
python 计算方位角实例(根据两点的坐标计算)
2020/01/17 Python
python爬取youtube视频的示例代码
2021/03/03 Python
常用UNIX 命令(Linux的常用命令)
2013/07/10 面试题
党员年终民主评议的自我评价
2013/11/05 职场文书
学生生病请假条范文
2014/02/16 职场文书
跳蚤市场口号
2014/06/13 职场文书
优秀党务工作者先进事迹材料
2014/12/25 职场文书
化工生产实习心得体会
2016/01/22 职场文书
pytorch训练神经网络爆内存的解决方案
2021/05/22 Python
Vue实现动态查询规则生成组件
2021/05/27 Vue.js
排查MySQL生产环境索引没有效果
2022/04/11 MySQL