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的ORM框架SQLAlchemy入门教程
Apr 28 Python
使用Python发送邮件附件以定时备份MySQL的教程
Apr 25 Python
python列表操作之extend和append的区别实例分析
Jul 28 Python
举例讲解Linux系统下Python调用系统Shell的方法
Nov 07 Python
Python开发微信公众平台的方法详解【基于weixin-knife】
Jul 08 Python
Python数字图像处理之霍夫线变换实现详解
Jan 12 Python
Python3.6安装及引入Requests库的实现方法
Jan 24 Python
对Python使用mfcc的两种方式详解
Jan 09 Python
python对XML文件的操作实现代码
Mar 27 Python
给keras层命名,并提取中间层输出值,保存到文档的实例
May 23 Python
简单的Python人脸识别系统
Jul 14 Python
浅谈怎么给Python添加类型标注
Jun 08 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递归复制、移动目录的自定义函数分享
2014/11/18 PHP
php操作xml入门之xml基本介绍及xml标签元素
2015/01/23 PHP
PHP框架laravel的.env文件配置教程
2017/06/07 PHP
PHP实现微信支付(jsapi支付)流程步骤详解
2018/03/15 PHP
JavaScript中的Screen屏幕对象
2008/01/16 Javascript
jQuery学习笔记(3)--用jquery(插件)实现多选项卡功能
2013/04/08 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
2013/05/03 Javascript
javascript完美拖拽的实现方法
2013/09/29 Javascript
使用jquery.validate自定义方法实现&quot;手机号码或者固话至少填写一个&quot;的逻辑验证
2014/09/01 Javascript
输入框过滤非数字的js代码
2014/09/18 Javascript
js实现的页面矩阵图形变换特效
2016/01/26 Javascript
js实现刷新页面后回到记录时滚动条的位置【两种方案可选】
2016/12/12 Javascript
纯JS单页面赛车游戏制作代码分享
2017/03/03 Javascript
微信小程序 实现列表项滑动显示删除按钮的功能
2017/04/13 Javascript
React 组件间的通信示例
2018/06/14 Javascript
js实现淘宝首页的banner栏效果
2019/11/26 Javascript
浅谈Tensorflow由于版本问题出现的几种错误及解决方法
2018/06/13 Python
Python中那些 Pythonic的写法详解
2019/07/02 Python
Python 列表去重去除空字符的例子
2019/07/20 Python
基于Python实现2种反转链表方法代码实例
2020/07/06 Python
python打包多类型文件的操作方法
2020/09/21 Python
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
欧洲品牌瓷器餐具网上商店:Porzellantreff.de
2018/04/04 全球购物
德国电子产品购物网站:TechInTheBasket德国
2018/12/07 全球购物
美体小铺印度官网:The Body Shop印度
2019/10/17 全球购物
Charles&Keith美国官方网站:新加坡快时尚鞋类和配饰零售商
2019/11/27 全球购物
电气工程及其自动化自我评价四篇
2013/09/24 职场文书
《桥》教学反思
2014/04/09 职场文书
学生请假条格式
2014/04/11 职场文书
电工技术比武方案
2014/05/11 职场文书
求职自我推荐信
2014/06/25 职场文书
中学生旷课检讨书500字
2014/10/29 职场文书
2014年销售助理工作总结
2014/12/01 职场文书
2015年音乐教研组工作总结
2015/07/22 职场文书
2016年优秀党务工作者先进事迹材料
2016/02/29 职场文书
Python接口自动化之文件上传/下载接口详解
2022/04/05 Python