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的Django框架中的通用视图
May 04 Python
python开发之函数定义实例分析
Nov 12 Python
Python设计模式之中介模式简单示例
Jan 09 Python
python脚本监控Tomcat服务器的方法
Jul 06 Python
Python多进程与服务器并发原理及用法实例分析
Aug 21 Python
Flask框架踩坑之ajax跨域请求实现
Feb 22 Python
Django 使用easy_thumbnails压缩上传的图片方法
Jul 26 Python
解决Python paramiko 模块远程执行ssh 命令 nohup 不生效的问题
Jul 14 Python
Python远程方法调用实现过程解析
Jul 28 Python
Python 如何查找特定类型文件
Aug 17 Python
Python爬虫实现自动登录、签到功能的代码
Aug 20 Python
Python中requests库的用法详解
Jun 05 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
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
2013/05/07 PHP
php自定义函数转换html标签示例
2016/09/29 PHP
Laravel框架源码解析之入口文件原理分析
2020/05/14 PHP
javascript 字符 Escape,encodeURI,encodeURIComponent
2009/07/09 Javascript
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
2010/03/16 Javascript
JS增加行复制行删除行的实现代码
2013/11/09 Javascript
jQuery实现异步获取json数据的2种方式
2014/08/29 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
将页面table内容与样式另存成excel文件的方法
2015/08/05 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
jQuery简单动画变换效果实例分析
2016/07/04 Javascript
jQuery 特性操作详解及实例代码
2016/09/29 Javascript
利用React-router+Webpack快速构建react程序
2016/10/27 Javascript
React快速入门教程
2017/01/17 Javascript
js实现4个方向滚动的球
2017/03/06 Javascript
jQuery发请求传输中文参数乱码问题的解决方案
2018/05/22 jQuery
javascript中的event loop事件循环详解
2018/12/14 Javascript
微信小程序实现通过双向滑动缩放图片大小的方法
2018/12/30 Javascript
手把手教你实现 Promise的使用方法
2020/09/02 Javascript
详解Python中expandtabs()方法的使用
2015/05/18 Python
浅析Python中yield关键词的作用与用法
2016/11/29 Python
python编程实现归并排序
2017/04/14 Python
Python运维开发之psutil库的使用详解
2018/10/18 Python
Spring Cloud Feign高级应用实例详解
2019/12/10 Python
解决springboot yml配置 logging.level 报错问题
2020/02/21 Python
Python3将ipa包中的文件按大小排序
2020/04/17 Python
python中adb有什么功能
2020/06/07 Python
浅析Python中字符串的intern机制
2020/10/03 Python
Numpy数组的广播机制的实现
2020/11/03 Python
python实现定时发送邮件
2020/12/23 Python
Expedia瑞典官网:预订度假屋、酒店、汽车租赁、机票等
2021/01/23 全球购物
法学个人求职信范文
2014/01/27 职场文书
招商专员岗位职责
2014/02/08 职场文书
豆瓣2021评分最高动画剧集-豆瓣评分最高的动画剧集2021
2022/03/18 日漫
vue3不同环境下实现配置代理
2022/05/25 Vue.js
Windows server 2022创建创建林、域树、子域的步骤
2022/06/25 Servers