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使用PyCrypto实现AES加密功能示例
May 22 Python
python实现远程通过网络邮件控制计算机重启或关机
Feb 22 Python
对python 矩阵转置transpose的实例讲解
Apr 17 Python
python实现在图片上画特定大小角度矩形框
Oct 24 Python
在python plt图表中文字大小调节的方法
Jul 08 Python
Python自动采集微信联系人的实现示例
Feb 28 Python
Pyqt5 关于流式布局和滚动条的综合使用示例代码
Mar 24 Python
详解python方法之绑定方法与非绑定方法
Aug 17 Python
python Cartopy的基础使用详解
Nov 01 Python
python全栈开发语法总结
Nov 22 Python
python爬取微博评论的实例讲解
Jan 15 Python
python神经网络ResNet50模型
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 CURL模拟GET及POST函数代码
2010/04/25 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
2013/01/23 PHP
解析PHP中一些可能会被忽略的问题
2013/06/21 PHP
PHP使用ActiveMQ实例
2018/02/05 PHP
设定php简写功能的方法
2019/11/28 PHP
TP3.2.3框架文件上传操作实例详解
2020/01/23 PHP
PHP 与 js的通信(via ajax,json)
2010/11/16 Javascript
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
Jquery增加鼠标中间功能mousewheel的实例代码
2013/09/05 Javascript
动态添加option及createElement使用示例
2014/01/26 Javascript
jQuery针对各类元素操作基础教程
2014/08/29 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
jQuery获取radio选中项的值实例
2016/06/18 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
详解vue中axios的封装
2018/07/18 Javascript
详解angularjs4部署文件过大解决过程
2018/12/05 Javascript
JavaScript Reflect Metadata实现详解
2019/12/12 Javascript
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
使用Python实现一个简单的项目监控
2015/03/31 Python
python实现指定字符串补全空格的方法
2015/04/30 Python
python爬虫基本知识
2018/03/05 Python
python爬虫的数据库连接问题【推荐】
2018/06/25 Python
Python使用pymysql从MySQL数据库中读出数据的方法
2018/07/25 Python
python利用itertools生成密码字典并多线程撞库破解rar密码
2019/08/12 Python
Django+python服务器部署与环境部署教程详解
2020/03/30 Python
非常漂亮的CSS3百叶窗焦点图动画
2016/02/24 HTML / CSS
Links of London官方网站:英国标志性的珠宝品牌
2017/04/09 全球购物
怎样声明子类
2013/07/02 面试题
历史学专业毕业生求职信
2013/09/27 职场文书
行政工作个人的自我评价
2014/02/13 职场文书
2014基层党员干部学习全国两会心得体会
2014/03/17 职场文书
医院义诊活动总结
2014/07/04 职场文书
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
毕业生自荐材料范文
2014/12/30 职场文书
入党自传范文2015
2015/06/26 职场文书
为什么阅读对所有年龄段的孩子都很重要?
2019/07/08 职场文书