Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则 wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复 这一过程,从而解决复杂的同步问题。

可以认为Condition对象维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对 象,当调用wait方法时,线程会释放Condition内部的锁并进入blocked状态,同时在waiting池中记录这个线程。当调用notify 方法时,Condition对象会从waiting池中挑选一个线程,通知其调用acquire方法尝试取到锁。

Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,如果没有指定,则Condition对象会在内部自行创建一个RLock。

除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire内部 锁。由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有线程永远处于沉默状态。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import threading
import time

class Producer(threading.Thread):
    def run(self):
        global count
        while True:
            if con.acquire():
                if count > 1000:
                    con.wait()
                else:
                    count += 100
                    msg = self.name + 'produce 100, count = '+ str(count)
                    print msg
                    con.notify()
                con.release()
                time.sleep(1)

class Consumer(threading.Thread):
    def run(self):
        global count
        while True:
            if con.acquire():
                if count < 100:
                    con.wait()
                else:
                    count -= 3
                    msg = self.name + ' consume 3, count = ' + str(count)
                    print msg
                    con.notify()
                con.release()
                time.sleep(1)

count = 500
con =threading.Condition()

def test():
    for i in range(2):
        p = Producer()
        p.start()
    for i in range(5):
        c = Consumer()
        c.start()

if __name__ == '__main__':
    test()

最新文章

  1. JAVA 引入 junit工具框架
  2. [No00006A]Js的addEventListener()及attachEvent()区别分析【js中的事件监听】
  3. 【原】iOS学习47之第三方-FMDB
  4. AutoTest简介
  5. cocos2dx 安卓编译问题收集
  6. 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符&quot;go&quot;时,第一个只出现一次的字符是&quot;g&quot;。当从该字符流中读出前六个字符“google&quot;时,第一个只出现一次的字符是&quot;l&quot;。
  7. 硬件和软件兼容i2c协议的24Cxx系列EEPROM存储器(转)
  8. 《Android源码设计模式》学习笔记之ImageLoader
  9. UltraISO安装centos7系统
  10. 自制vbs消息轰炸机
  11. 1 eclipse 离线安装activiti插件
  12. Web从入门到放弃&lt;2&gt;
  13. 2019春第十周作业Compile Summarize
  14. Markdown编辑工具及命令
  15. 解决Intellij IDEA中console窗口中文乱码的问题
  16. Git 恢复本地误删的文件
  17. easyui combobox 动态加载数据C#
  18. SQL Server中ORDER BY后面可以是表达式和子查询
  19. sublime text3 设置快速生成代码
  20. 第二阶段Sprint6

热门文章

  1. BZOJ 3153 Sone1
  2. 王学长的AAA树
  3. ortp使用详解2
  4. ubuntu 创建eclipse 快捷方式
  5. Delphi TStringList的用法
  6. android后台截屏实现(1)--源码编译
  7. linux增大交换分区
  8. Python序列的方法(转)
  9. AngularJs练习Demo14自定义服务
  10. java下udp的DatagramSocket 发送与接收