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中运算符使用时的优先级
May 14 Python
python下载文件记录黑名单的实现代码
Oct 24 Python
Python 利用内置set函数对字符串和列表进行去重的方法
Jun 29 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
python实现函数极小值
Jul 10 Python
Django框架视图函数设计示例
Jul 29 Python
Django实现文件上传下载功能
Oct 06 Python
Python 多线程共享变量的实现示例
Apr 17 Python
python selenium xpath定位操作
Sep 01 Python
解决Ubuntu18中的pycharm不能调用tensorflow-gpu的问题
Sep 17 Python
python实现银行账户系统
Feb 22 Python
python Protobuf定义消息类型知识点讲解
Mar 02 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中将数组存到文件里的实现代码
2012/01/19 PHP
extjs 学习笔记(三) 最基本的grid
2009/10/15 Javascript
jQuery学习笔记之Helloworld
2010/12/22 Javascript
ie下动态加态js文件的方法
2011/09/13 Javascript
js实现点击注册按钮开始读秒倒计时的小例子
2013/05/11 Javascript
javascript实现获取字符串hash值
2015/05/10 Javascript
基于jquery实现省市区三级联动效果
2015/12/25 Javascript
JS中sort函数排序用法实例分析
2016/06/16 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
2017/02/21 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
浅谈ES6新增的数组方法和对象
2017/08/08 Javascript
通过源码分析Vue的双向数据绑定详解
2017/09/24 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
详解在HTTPS 项目中使用百度地图 API
2019/04/26 Javascript
vue store之状态管理模式的详细介绍
2019/06/13 Javascript
原生js实现瀑布流效果
2020/03/09 Javascript
详细解读Python中解析XML数据的方法
2015/10/15 Python
Python单链表简单实现代码
2016/04/27 Python
浅谈Python2.6和Python3.0中八进制数字表示的区别
2017/04/28 Python
python利用urllib和urllib2访问http的GET/POST详解
2017/09/27 Python
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
Python实现删除排序数组中重复项的两种方法示例
2019/01/31 Python
打包python 加icon 去掉cmd黑窗口方法
2019/06/24 Python
Djang的model创建的字段和参数详解
2019/07/27 Python
python操作gitlab API过程解析
2019/12/27 Python
学雷锋志愿服务月活动总结
2014/03/09 职场文书
合作协议书范本
2014/04/17 职场文书
体育之星事迹材料
2014/05/11 职场文书
班级出游活动计划书
2014/08/15 职场文书
狼牙山五壮士观后感
2015/06/09 职场文书
感恩教育观后感
2015/06/17 职场文书
使用Selenium实现微博爬虫(预登录、展开全文、翻页)
2021/04/13 Python
PHP设计模式(观察者模式)
2021/07/07 PHP
springboot应用服务启动事件的监听实现
2022/04/06 Java/Android