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爬虫之爬虫框架Scrapy安装配置
Nov 06 Python
Python处理字符串之isspace()方法的使用
May 19 Python
Python做文本按行去重的实现方法
Oct 19 Python
django 实现电子支付功能的示例代码
Jul 25 Python
numpy中loadtxt 的用法详解
Aug 03 Python
解决python opencv无法显示图片的问题
Oct 28 Python
Python 微信之获取好友昵称并制作wordcloud的实例
Feb 21 Python
python标记语句块使用方法总结
Aug 05 Python
Python IDE Pycharm中的快捷键列表用法
Aug 08 Python
python conda操作方法
Sep 11 Python
python 数据库查询返回list或tuple实例
May 15 Python
django实现日志按日期分割
May 21 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 获取远程网页内容的函数
2009/09/08 PHP
php中去除所有js,html,css代码
2010/10/12 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
php中get_headers函数的作用及用法的详细介绍
2013/04/27 PHP
Json_decode 解析json字符串为NULL的解决方法(必看)
2017/02/17 PHP
javascript第一课
2007/02/27 Javascript
javascript入门·对象属性方法大总结
2007/10/01 Javascript
JavaScript 继承详解(一)
2009/07/13 Javascript
jQuery AJAX回调函数this指向问题
2010/02/08 Javascript
理解jQuery stop()方法
2014/11/21 Javascript
jquery选择器需要注意的问题
2014/11/26 Javascript
封装了jQuery的Ajax请求全局配置
2015/02/05 Javascript
jQuery插件slick实现响应式移动端幻灯片图片切换特效
2015/04/12 Javascript
jQuery检测返回值的数据类型
2015/07/13 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
微信小程序本作用域下调用全局JS详解及实例
2017/02/22 Javascript
Javascript Symbol原理及使用方法解析
2020/10/22 Javascript
一篇文章看懂JavaScript中的回调
2021/01/05 Javascript
vue 计算属性和侦听器的使用小结
2021/01/25 Vue.js
[02:28]DOTA2英雄基础教程 狼人
2013/12/23 DOTA
[06:36]吞吞映像top1
2014/06/20 DOTA
Django实现图片文字同时提交的方法
2015/05/26 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
在pycharm中实现删除bookmark
2020/02/14 Python
世界上最大的在线旅行社新加坡网站:Expedia新加坡
2016/08/25 全球购物
英国网上购买门:Direct Doors
2018/06/07 全球购物
毕业生个人求职信范例分享
2013/12/17 职场文书
ktv中秋节活动方案
2014/01/30 职场文书
班组建设经验交流材料
2014/05/12 职场文书
2015年信息中心工作总结
2015/05/25 职场文书
可可西里观后感
2015/06/08 职场文书
廉洁自律证明
2015/06/24 职场文书
2016继续教育研修日志
2015/11/13 职场文书
2016习总书记系列重要讲话心得体会
2016/01/15 职场文书
nginx设置资源请求目录的方式详解
2022/05/30 Servers