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如何修改装饰器中参数
Mar 20 Python
对python中raw_input()和input()的用法详解
Apr 22 Python
Python3.6通过自带的urllib通过get或post方法请求url的实例
May 10 Python
Python使用jsonpath-rw模块处理Json对象操作示例
Jul 31 Python
Python面向对象之继承和组合用法实例分析
Aug 27 Python
浅谈Python采集网页时正则表达式匹配换行符的问题
Dec 20 Python
python调用接口的4种方式代码实例
Nov 19 Python
python 列表、字典和集合的添加和删除操作
Dec 16 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
May 15 Python
keras之权重初始化方式
May 21 Python
Python函数的迭代器与生成器的示例代码
Jun 18 Python
python openpyxl模块的使用详解
Feb 25 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获取网卡地址的代码
2008/04/09 PHP
php 保留小数点
2009/04/21 PHP
php用户注册时常用的检验函数实例总结
2014/12/22 PHP
php将图片保存为不同尺寸图片的图片类实例
2015/03/30 PHP
php实现微信模板消息推送
2018/03/30 PHP
PHP实现倒计时功能
2020/11/16 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
在模板页面的js使用办法
2010/04/01 Javascript
Javascript Function对象扩展之延时执行函数
2010/07/06 Javascript
javascript中全局对象的parseInt()方法使用介绍
2013/12/19 Javascript
javascript 实现子父窗体互相传值的简单实例
2014/02/17 Javascript
简述JavaScript中正则表达式的使用方法
2015/06/15 Javascript
javascript实现10个球随机运动、碰撞实例详解
2015/07/08 Javascript
JS实现不规则TAB选项卡效果代码
2015/09/16 Javascript
javascript HTML5 Canvas实现圆盘抽奖功能
2016/04/11 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
利用node.js实现自动生成前端项目组件的方法详解
2017/07/12 Javascript
JavaScript常见JSON操作实例分析
2018/08/08 Javascript
微信小程序 动态修改页面数据及参数传递过程详解
2019/09/27 Javascript
JS实现滑动插件
2020/01/15 Javascript
JavaScript面试中常考的字符串操作方法大全(包含ES6)
2020/05/10 Javascript
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
python实现按行切分文本文件的方法
2016/04/18 Python
详解python中字典的循环遍历的两种方式
2017/02/07 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
2020/07/20 Python
Anaconda 离线安装 python 包的操作方法
2018/06/11 Python
python中的句柄操作的方法示例
2019/06/20 Python
Python爬虫谷歌Chrome F12抓包过程原理解析
2020/06/04 Python
关于tensorflow softmax函数用法解析
2020/06/30 Python
HTML5中Localstorage的使用教程
2015/07/09 HTML / CSS
总会计师岗位职责
2014/02/19 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
教师节演讲稿
2014/05/06 职场文书
学校实习推荐信
2015/03/27 职场文书
2016年社区植树节活动总结
2016/03/16 职场文书
Win10本地连接不见了怎么恢复? win10系统电脑本地连接不见了解决方法
2023/01/09 数码科技