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中lambda的用法及其与def的区别解析
Jul 28 Python
python实现红包裂变算法
Feb 16 Python
python爬虫入门教程--正则表达式完全指南(五)
May 25 Python
python 多维切片之冒号和三个点的用法介绍
Apr 19 Python
python+influxdb+shell编写区域网络状况表
Jul 27 Python
Python发展简史 Python来历
May 14 Python
利用pyuic5将ui文件转换为py文件的方法
Jun 19 Python
pycharm设置python文件模板信息过程图解
Mar 10 Python
Python flask框架如何显示图像到web页面
Jun 03 Python
python3爬虫GIL修改多线程实例讲解
Nov 24 Python
教你怎么用Python监控愉客行车程
Apr 29 Python
Python中else的三种使用场景
Jun 16 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如何防止XSS攻击与XSS攻击原理的讲解
2019/03/22 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
jquery 中多条件选择器,相对选择器,层次选择器的区别
2012/07/03 Javascript
js 使FORM表单的所有元素不可编辑的示例代码
2013/10/17 Javascript
自制的文件上传JS控件可支持IE、chrome、firefox etc
2014/04/18 Javascript
js/jquery判断浏览器的方法小结
2014/09/02 Javascript
jquery实现将获取的颜色值转换为十六进制形式的方法
2014/12/20 Javascript
js面向对象之静态方法和静态属性实例分析
2015/01/10 Javascript
JS实现网页滚动条感应鼠标变色的方法
2015/02/26 Javascript
jquery左右全屏大尺寸多图滑动效果代码分享
2015/08/28 Javascript
jQuery ajax应用总结
2016/06/02 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
2016/11/07 Javascript
bootstrap datetimepicker实现秒钟选择下拉框
2017/01/05 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
详解vue-router 2.0 常用基础知识点之router.push()
2017/05/10 Javascript
js 索引下标之li集合绑定点击事件
2018/01/12 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
记录一次websocket封装的过程
2020/11/23 Javascript
Python Pandas找到缺失值的位置方法
2018/04/12 Python
Python数据分析matplotlib设置多个子图的间距方法
2018/08/03 Python
python爬虫 execjs安装配置及使用
2019/07/30 Python
基于python3抓取pinpoint应用信息入库
2020/01/08 Python
python的json包位置及用法总结
2020/06/21 Python
Django+RestFramework API接口及接口文档并返回json数据操作
2020/07/12 Python
Python中实现一行拆多行和多行并一行的示例代码
2020/09/06 Python
用C语言实现文件读写操作
2013/10/27 面试题
现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset
2012/11/09 面试题
运动会广播稿200米
2014/01/27 职场文书
机械加工与数控专业自荐书
2014/06/04 职场文书
创建文明城市标语
2014/06/16 职场文书
求职意向书
2014/07/29 职场文书
心得体会的写法
2014/09/05 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
用JS创建一个录屏功能
2021/11/11 Javascript