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 相关文章推荐
Django中使用celery完成异步任务的示例代码
Jan 23 Python
用python编写第一个IDA插件的实例
May 29 Python
pandas将numpy数组写入到csv的实例
Jul 04 Python
我们为什么要减少Python中循环的使用
Jul 10 Python
python cumsum函数的具体使用
Jul 29 Python
python实现操作文件(文件夹)
Oct 31 Python
Django中modelform组件实例用法总结
Feb 10 Python
Python3爬虫里关于Splash负载均衡配置详解
Jul 10 Python
利用python汇总统计多张Excel
Sep 22 Python
python爬取音频下载的示例代码
Oct 19 Python
Restful_framework视图组件代码实例解析
Nov 17 Python
Django利用AJAX技术实现博文实时搜索
May 06 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用数组返回无限分类的列表数据的代码
2010/08/08 PHP
php实现图片上传时添加文字和图片水印技巧
2020/04/18 PHP
Yii隐藏URL中index.php的方法
2016/07/12 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
phpinfo无法显示的原因及解决办法
2019/02/15 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
什么是JavaScript
2009/08/13 Javascript
JQUERY的属性选择符和自定义选择符使用方法(二)
2011/04/07 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
2013/01/16 Javascript
js判断一个字符串是否包含一个子串的方法
2015/01/26 Javascript
Jquery 实现checkbox全选方法
2015/01/28 Javascript
JavaScript类继承及实例化的方法
2015/07/25 Javascript
JS特效实现图片自动播放并可控的效果
2015/07/31 Javascript
jQuery+Ajax+PHP弹出层异步登录效果(附源码下载)
2016/05/27 Javascript
js实现对table的增加行和删除行的操作方法
2016/10/13 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
JavaScript实现替换字符串中最后一个字符的方法
2017/03/07 Javascript
JS使用插件cryptojs进行加密解密数据实例
2017/05/11 Javascript
Bootstrap实现的标签页内容切换显示效果示例
2017/05/25 Javascript
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
Vue 中使用 CSS Modules优雅方法
2018/04/09 Javascript
vue如何解决循环引用组件报错的问题
2018/09/22 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
vue 导出文件,携带请求头token操作
2020/09/10 Javascript
Python中多线程的创建及基本调用方法
2016/07/08 Python
Python标准模块--ContextManager上下文管理器的具体用法
2017/11/27 Python
Linux下python与C++使用dlib实现人脸检测
2018/06/29 Python
python查看文件大小和文件夹内容的方法
2019/07/08 Python
Python中bisect的使用方法
2019/12/31 Python
matplotlib quiver箭图绘制案例
2020/04/17 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
2020/05/22 Python
澳大利亚旅游网站:Lastminute
2017/08/07 全球购物
宏碁西班牙官网:Acer西班牙
2021/01/08 全球购物
玄武湖导游词
2015/02/05 职场文书
团员个人年度总结
2015/02/26 职场文书
加班费申请报告
2015/05/15 职场文书