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的Tornado框架实现数据可视化的教程
May 02 Python
Python下Fabric的简单部署方法
Jul 14 Python
Python爬虫模拟登录带验证码网站
Jan 22 Python
浅析Python中的getattr(),setattr(),delattr(),hasattr()
Jun 14 Python
Python Socket使用实例
Dec 18 Python
python并发编程之线程实例解析
Dec 27 Python
Python中super函数用法实例分析
Mar 18 Python
numpy和pandas中数组的合并、拉直和重塑实例
Jun 28 Python
django-allauth入门学习和使用详解
Jul 03 Python
react+django清除浏览器缓存的几种方法小结
Jul 17 Python
python:HDF和CSV存储优劣对比分析
Jun 08 Python
Python 获取异常(Exception)信息的几种方法
Dec 29 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实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
PHP检查URL包含特定字符串实例方法
2019/02/11 PHP
实例:用 JavaScript 来操作字符串(一些字符串函数)
2007/02/15 Javascript
利用404错误页面实现UrlRewrite的实现代码
2008/08/20 Javascript
用js判断页面刷新或关闭的方法(onbeforeunload与onunload事件)
2012/06/22 Javascript
Js 代码中,ajax请求地址后加随机数防止浏览器缓存的原因
2013/05/07 Javascript
解析JavaScript中的不可见数据类型
2013/12/02 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
jQuery之简单的表单验证实例
2016/07/07 Javascript
清除输入框内的空格
2016/12/21 Javascript
angularJS+requireJS实现controller及directive的按需加载示例
2017/02/20 Javascript
jquery实现自定义图片裁剪功能【推荐】
2017/03/08 Javascript
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
2018/09/12 Javascript
爬虫利器Puppeteer实战
2019/01/09 Javascript
JavaScript变速动画函数封装添加任意多个属性
2019/04/03 Javascript
详解vue中v-on事件监听指令的基本用法
2020/07/22 Javascript
在Python中关于中文编码问题的处理建议
2015/04/08 Python
改进Django中的表单的简单方法
2015/07/17 Python
Python利用BeautifulSoup解析Html的方法示例
2017/07/30 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
Python cookbook(数据结构与算法)将序列分解为单独变量的方法
2018/02/13 Python
完美解决Django2.0中models下的ForeignKey()问题
2020/05/19 Python
Python 如何在字符串中插入变量
2020/08/01 Python
python自动生成sql语句的脚本
2021/02/24 Python
纯CSS3实现手风琴风格菜单具体步骤
2013/05/06 HTML / CSS
营业员演讲稿
2013/12/30 职场文书
校园公益广告语
2014/03/13 职场文书
应届大专生自荐书
2014/06/16 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
2015社区六五普法工作总结
2015/04/21 职场文书
小学语文教学随笔
2015/08/14 职场文书
导游词之西湖雷峰塔
2019/09/18 职场文书
css弧边选项卡的项目实践
2023/05/07 HTML / CSS