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中编写数据库模块的教程
Apr 29 Python
python中while循环语句用法简单实例
May 07 Python
Python中DJANGO简单测试实例
May 11 Python
Python中的集合类型知识讲解
Aug 19 Python
Python正则表达式常用函数总结
Jun 24 Python
Python数据结构之单链表详解
Sep 12 Python
使用Django启动命令行及执行脚本的方法
May 29 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
Nov 07 Python
如何解决tensorflow恢复模型的特定值时出错
Feb 06 Python
python 实现图片修复(可用于去水印)
Nov 19 Python
Pyqt助手安装PyQt5帮助文档过程图解
Nov 20 Python
python3使用diagrams绘制架构图的步骤
Apr 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
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
PHP,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解决方法
2014/11/04 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
2017/07/10 PHP
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
2006/09/22 Javascript
javascript时间函数大全
2014/06/30 Javascript
jquery+json实现分页效果
2016/03/07 Javascript
JavaScript 节流函数 Throttle 详解
2016/07/04 Javascript
最简单纯JavaScript实现Tab标签页切换的方式(推荐)
2016/07/25 Javascript
用原生js做单页应用
2017/01/17 Javascript
vue.js中过滤器的使用教程
2017/06/08 Javascript
3种vue组件的书写形式
2017/11/29 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
详解angularjs4部署文件过大解决过程
2018/12/05 Javascript
JavaScript工具库MyTools详解
2020/01/01 Javascript
OpenLayer学习之自定义测量控件
2020/09/28 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
Python实现一个简单的验证码程序
2017/11/03 Python
python导出hive数据表的schema实例代码
2018/01/22 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
Python实现的寻找前5个默尼森数算法示例
2018/03/25 Python
python 3.6.4 安装配置方法图文教程
2018/09/18 Python
Python如何调用JS文件中的函数
2019/08/16 Python
django中使用POST方法获取POST数据
2019/08/20 Python
Python vtk读取并显示dicom文件示例
2020/01/13 Python
tensorflow获取预训练模型某层参数并赋值到当前网络指定层方式
2020/01/24 Python
哈利波特商店:Harry Potter Shop
2018/11/30 全球购物
计算机专业推荐信范文
2013/11/20 职场文书
农村党支部先进事迹
2014/01/14 职场文书
《晏子使楚》教学反思
2014/02/08 职场文书
老公爱的承诺书
2014/03/31 职场文书
社会实践活动总结范文
2014/07/03 职场文书
护士自我推荐信范文
2015/03/24 职场文书
python实现图片批量压缩
2021/04/24 Python
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫
Android 中的类文件和类加载器详情
2022/06/05 Java/Android