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迭代和迭代器详解
Nov 10 Python
Python爬取当当、京东、亚马逊图书信息代码实例
Dec 09 Python
使用pandas中的DataFrame数据绘制柱状图的方法
Apr 10 Python
Python FTP两个文件夹间的同步实例代码
May 25 Python
python 列表,数组和矩阵sum的用法及区别介绍
Jun 28 Python
python字典的setdefault的巧妙用法
Aug 07 Python
python如果快速判断数字奇数偶数
Nov 13 Python
python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法
Feb 27 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
Jun 02 Python
如何用Python 加密文件
Sep 10 Python
Python爬取梨视频的示例
Jan 29 Python
python sleep和wait对比总结
Feb 03 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+.htaccess实现全站静态HTML文件GZIP压缩传输(一)
2007/02/15 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
java微信开发之上传下载多媒体文件
2016/06/24 PHP
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
php从数据库中获取数据用ajax传送到前台的方法
2018/08/20 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
2019/04/04 PHP
JS实现下拉框的动态添加(附效果)
2013/04/03 Javascript
javascript简单实现表格行间隔显示颜色并高亮显示
2013/11/29 Javascript
一个jquery实现的不错的多行文字图片滚动效果
2014/09/28 Javascript
JavaScript实现给按钮加上双重动作的方法
2015/08/14 Javascript
关于javascript中dataset的问题小结
2015/11/16 Javascript
js实现多图左右切换功能
2016/08/04 Javascript
利用Node.js编写跨平台的spawn语句详解
2017/02/12 Javascript
layui实现table加载的示例代码
2018/08/14 Javascript
JS实现动态星空背景效果
2019/11/01 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
[01:36:17]DOTA2-DPC中国联赛 正赛 Ehome vs iG BO3 第一场 1月31日
2021/03/11 DOTA
Python首次安装后运行报错(0xc000007b)的解决方法
2016/10/18 Python
Python实现KNN邻近算法
2021/01/28 Python
详解Python判定IP地址合法性的三种方法
2018/03/06 Python
浅谈python函数调用返回两个或多个变量的方法
2019/01/23 Python
Python按钮的响应事件详解
2019/03/04 Python
Django Rest framework频率原理与限制
2019/07/26 Python
python根据多个文件名批量查找文件
2019/08/13 Python
python3多线程知识点总结
2019/09/26 Python
python matplotlib折线图样式实现过程
2019/11/04 Python
彻底解决Python包下载慢问题
2020/11/15 Python
python3 os进行嵌套操作的实例讲解
2020/11/19 Python
数据库连接池的工作原理
2012/09/26 面试题
竞聘上岗演讲稿范文
2014/01/10 职场文书
小学优秀班主任事迹材料
2014/05/17 职场文书
2015年小学一年级班主任工作总结
2015/05/21 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
Python基础之Socket通信原理
2021/04/22 Python
用php如何解决大文件分片上传问题
2021/07/07 PHP
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python