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的轻便web框架Bottle
Apr 08 Python
Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
May 17 Python
django批量导入xml数据
Oct 16 Python
Python在图片中添加文字的两种方法
Apr 29 Python
Linux RedHat下安装Python2.7开发环境
May 20 Python
放弃 Python 转向 Go语言有人给出了 9 大理由
Oct 20 Python
python中的decorator的作用详解
Jul 26 Python
实例讲解python中的序列化知识点
Oct 08 Python
浅谈Pycharm调用同级目录下的py脚本bug
Dec 03 Python
python matplotlib实现双Y轴的实例
Feb 12 Python
pyinstaller将含有多个py文件的python程序做成exe
Apr 29 Python
Python绘制分类图的方法
Apr 20 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中的函数-- foreach()的用法详解
2013/06/24 PHP
php调用C代码的实现方法
2014/03/11 PHP
THINKPHP内容分页代码分享
2015/01/14 PHP
php实现粘贴截图并完成上传功能
2015/05/17 PHP
thinkphp3.x中变量的获取和过滤方法详解
2016/05/20 PHP
PHP序列化操作方法分析
2016/09/28 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
2017/03/04 PHP
详解PHP中的 input属性(隐藏 只读 限制)
2017/08/14 PHP
PHP7 安装event扩展的实现方法
2019/10/08 PHP
Js+Dhtml:WEB程序员简易开发工具包(预先体验版)
2006/11/07 Javascript
jQuery.autocomplete 支持中文输入(firefox)修正方法
2011/03/10 Javascript
jQuery学习笔记(1)--用jQuery实现异步通信(用json传值)具体思路
2013/04/08 Javascript
js动态调用css属性的小规律及实例说明
2013/12/28 Javascript
jQuery添加删除DOM元素方法详解
2016/01/18 Javascript
JAVA中截取字符串substring用法详解
2017/04/14 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
使用jquery DataTable和ajax向页面显示数据列表的方法
2018/08/09 jQuery
vue2中使用sass并配置全局的sass样式变量的方法
2018/09/04 Javascript
微信小程序分享海报生成的实现方法
2018/12/10 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
微信小程序点击顶部导航栏切换样式代码实例
2019/11/12 Javascript
JavaScript 类的封装操作示例详解
2020/05/16 Javascript
three.js 如何制作魔方
2020/07/31 Javascript
vue将data恢复到初始状态 &amp;&amp; 重新渲染组件实例
2020/09/04 Javascript
Python pass 语句使用示例
2014/03/11 Python
详解python项目实战:模拟登陆CSDN
2019/04/04 Python
PyQt Qt Designer工具的布局管理详解
2019/08/07 Python
python matplotlib:plt.scatter() 大小和颜色参数详解
2020/04/14 Python
Aerosoles爱柔仕官网:美国舒软女鞋品牌
2017/07/17 全球购物
可持续木材、生态和铝制太阳镜:Proof Eyewear
2019/07/24 全球购物
先进工作者获奖感言
2014/02/08 职场文书
本科生导师推荐信范文
2014/05/18 职场文书
四查四看自我剖析材料
2014/09/19 职场文书
2014年双拥工作总结
2014/11/21 职场文书
公司出纳岗位职责
2015/03/31 职场文书
SQL Server连接查询的实用教程
2021/04/07 SQL Server