Python多线程编程(七):使用Condition实现复杂同步


Posted in Python onApril 05, 2015

目前我们已经会使用Lock去对公共资源进行互斥访问了,也探讨了同一线程可以使用RLock去重入锁,但是尽管如此我们只不过才处理了一些程序中简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题。所以我们得学会使用更深层的解决同步问题。

Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。

使用Condition的主要方式为:线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。

下面我们通过很著名的“生产者-消费者”模型来来演示下,在Python中使用Condition实现复杂同步。

''' 

Created on 2012-9-8 

 

@author: walfred 

@module: thread.TreadTest7 

'''  

 

import threading  

import time  

 

condition = threading.Condition()  

products = 0  

 

class Producer(threading.Thread):  

    def __init__(self):  

        threading.Thread.__init__(self)  

 

    def run(self):  

        global condition, products  

        while True:  

            if condition.acquire():  

                if products < 10:  

                    products += 1;  

                    print "Producer(%s):deliver one, now products:%s" %(self.name, products)  

                    condition.notify()  

                else:  

                    print "Producer(%s):already 10, stop deliver, now products:%s" %(self.name, products)  

                    condition.wait();  

                condition.release()  

                time.sleep(2)  

 

class Consumer(threading.Thread):  

    def __init__(self):  

        threading.Thread.__init__(self)  

 

    def run(self):  

        global condition, products  

        while True:  

            if condition.acquire():  

                if products > 1:  

                    products -= 1  

                    print "Consumer(%s):consume one, now products:%s" %(self.name, products)  

                    condition.notify()  

                else:  

                    print "Consumer(%s):only 1, stop consume, products:%s" %(self.name, products)  

                    condition.wait();  

                condition.release()  

                time.sleep(2)  

 

if __name__ == "__main__":  

    for p in range(0, 2):  

        p = Producer()  

        p.start()  

 

    for c in range(0, 10):  

        c = Consumer()  

        c.start()

代码中主要实现了生产者和消费者线程,双方将会围绕products来产生同步问题,首先是2个生成者生产products ,而接下来的10个消费者将会消耗products,代码运行如下:

Producer(Thread-1):deliver one, now products:1

Producer(Thread-2):deliver one, now products:2

Consumer(Thread-3):consume one, now products:1

Consumer(Thread-4):only 1, stop consume, products:1

Consumer(Thread-5):only 1, stop consume, products:1

Consumer(Thread-6):only 1, stop consume, products:1

Consumer(Thread-7):only 1, stop consume, products:1

Consumer(Thread-8):only 1, stop consume, products:1

Consumer(Thread-10):only 1, stop consume, products:1

Consumer(Thread-9):only 1, stop consume, products:1

Consumer(Thread-12):only 1, stop consume, products:1

Consumer(Thread-11):only 1, stop consume, products:1

另外:Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock;除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有线程永远处于沉默状态。
Python 相关文章推荐
python 不关闭控制台的实现方法
Oct 23 Python
python聊天程序实例代码分享
Nov 18 Python
python计算书页码的统计数字问题实例
Sep 26 Python
Python如何import文件夹下的文件(实现方法)
Jan 24 Python
Python 模拟员工信息数据库操作的实例
Oct 23 Python
Python 3.7新功能之dataclass装饰器详解
Apr 21 Python
Vue的el-scrollbar实现自定义滚动
May 29 Python
浅析python的Lambda表达式
Feb 27 Python
如何在python中执行另一个py文件
Apr 30 Python
python 绘制国旗的示例
Sep 27 Python
Python中使用Lambda函数的5种用法
Apr 01 Python
python简单验证码识别的实现过程
Jun 20 Python
Python多线程编程(六):可重入锁RLock
Apr 05 #Python
Python多线程编程(五):死锁的形成
Apr 05 #Python
Python多线程编程(四):使用Lock互斥锁
Apr 05 #Python
Python多线程编程(三):threading.Thread类的重要函数和方法
Apr 05 #Python
Python多线程编程(二):启动线程的两种方法
Apr 05 #Python
Python多线程编程(一):threading模块综述
Apr 05 #Python
Python中使用dom模块生成XML文件示例
Apr 05 #Python
You might like
php函数间的参数传递(值传递/引用传递)
2013/09/23 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
如何解决phpmyadmin导入数据库文件最大限制2048KB
2015/10/09 PHP
微信开发之php表单微信中自动提交两次问题解决办法
2017/01/08 PHP
基于mootools插件实现遮罩层新手引导
2012/05/24 Javascript
E3 tree 1.6在Firefox下显示问题的修复方法
2013/01/30 Javascript
jquery的父子兄弟节点查找示例代码
2014/03/03 Javascript
jQuery时间轴插件使用详解
2015/07/16 Javascript
javascript实现input file上传图片预览效果
2015/12/31 Javascript
基于JavaScript实现全屏透明遮罩div层锁屏效果
2016/01/26 Javascript
js手动播放图片实现图片轮播效果
2016/09/17 Javascript
基于jQuery ligerUI实现分页样式
2016/09/18 Javascript
浅谈移动端之js touch事件 手势滑动事件
2016/11/07 Javascript
AngularJS表单验证功能分析
2017/05/26 Javascript
基于node.js之调试器详解
2017/08/22 Javascript
jQuery插件artDialog.js使用与关闭方法示例
2017/10/09 jQuery
AngularJS集合数据遍历显示的实例
2017/12/27 Javascript
浅谈React中组件间抽象
2018/01/27 Javascript
jQuery niceScroll滚动条错位问题的解决方法
2018/02/03 jQuery
python调用cmd复制文件代码分享
2013/12/27 Python
pyqt5之将textBrowser的内容写入txt文档的方法
2019/06/21 Python
PyQt5实现暗黑风格的计时器
2019/07/29 Python
使用python模拟命令行终端的示例
2019/08/13 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
40行Python代码实现天气预报和每日鸡汤推送功能
2020/02/27 Python
New Balance天猫官方旗舰店:始于1906年,百年慢跑品牌
2017/11/15 全球购物
Hotels.com越南:酒店预订
2019/10/29 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
工艺员岗位职责
2014/02/11 职场文书
财务人员担保书
2014/05/13 职场文书
2015年采购工作总结
2015/04/10 职场文书
2015年政府采购工作总结
2015/05/21 职场文书
2016党员党章学习心得体会
2016/01/14 职场文书
详解Django的MVT设计模式
2021/04/29 Python