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 查找文件夹下所有文件 实现代码
Jul 01 Python
Python NumPy库安装使用笔记
May 18 Python
Python常见格式化字符串方法小结【百分号与format方法】
Sep 18 Python
python字符串,数值计算
Oct 05 Python
python OpenCV学习笔记直方图反向投影的实现
Feb 07 Python
opencv python 基于KNN的手写体识别的实例
Aug 03 Python
python迭代器常见用法实例分析
Nov 22 Python
Pycharm中切换pytorch的环境和配置的教程详解
Mar 13 Python
Python实现迪杰斯特拉算法过程解析
Sep 18 Python
python 递归相关知识总结
Mar 03 Python
PyCharm 配置SSH和SFTP连接远程服务器
May 11 Python
LeetCode189轮转数组python示例
Aug 05 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面向对象的方法重载两种版本比较
2008/09/08 PHP
深入PHP中的HashTable结构详解
2013/06/13 PHP
php实现的数字验证码及数字运算验证码
2015/07/30 PHP
JS解密入门 最终变量劫持
2008/06/25 Javascript
JQuery 学习笔记 选择器之三
2009/07/23 Javascript
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
Extjs中通过Tree加载右侧TabPanel具体实现
2013/05/05 Javascript
js+css 实现遮罩居中弹出层(随浏览器窗口滚动条滚动)
2013/12/11 Javascript
JQuery显示隐藏DIV的方法及代码实例
2015/04/16 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
JS实现alert中显示换行的方法
2015/12/17 Javascript
VUE使用vuex解决模块间传值问题的方法
2017/06/01 Javascript
JS实现table表格固定表头且表头随横向滚动而滚动
2017/10/26 Javascript
Angular4绑定html内容出现警告的处理方法
2017/11/03 Javascript
Angular2使用vscode断点调试ts文件的方法
2017/12/13 Javascript
React 组件间的通信示例
2018/06/14 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
Vue利用Blob下载原生二进制数组文件
2019/09/25 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
javascript实现智能手环时间显示
2020/09/18 Javascript
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
Python聊天室实例程序分享
2016/01/05 Python
Python爬虫常用小技巧之设置代理IP
2018/09/13 Python
在python带权重的列表中随机取值的方法
2019/01/23 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
Tensorflow 卷积的梯度反向传播过程
2020/02/10 Python
Django基于Models定制Admin后台实现过程解析
2020/11/11 Python
详解Python 中的 defaultdict 数据类型
2021/02/22 Python
CSS3实现多背景模拟动态边框的效果
2016/11/08 HTML / CSS
.net面试题
2016/09/17 面试题
linux面试题参考答案(7)
2014/07/24 面试题
组织关系转移介绍信
2014/01/16 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
解析原生JS getComputedStyle
2021/05/25 Javascript
MySQL 中如何归档数据的实现方法
2022/03/16 SQL Server
Python中的turtle画箭头,矩形,五角星
2022/03/16 Python