python 线程之 Condition
admin
2023-07-31 00:36:17
0

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

thread-condition

除了上面画的acquire方法、 release方法、notify方法、wait方法外还有notifyAll方法,不过notifyAll方法不常用。

51cto博客上我看到一篇博文中,形象的以二人对话 (生产者-消费者模)来解释上面的具体理论。

thread-talk

其中空格哥对应原理图中的A函数 ,西米对应的B 函数,每句话是doing操作,空格哥未“doing” 前,西米需要一直等待。最后,你来我往,直到最后都release掉,对话结束。由于代码太长,我给个精简版的,模拟上面的对话:

1234567891011121314151617181920212223242526272829303132333435363738394041 #coding:utf-8#—- Condition#—- 捉迷藏的游戏import threading, timeclass Hider(threading.Thread):    def __init__(self, cond, name):        super(Hider, self).__init__()        self.cond = cond        self.name = name    def run(self):        time.sleep(1) #确保先运行Seeker中的方法        self.cond.acquire() #b        print self.name + \’: 我已经把眼睛蒙上了\’        self.cond.notify()        self.cond.wait() #c                         #f        print self.name + \’: 我找到你了 ~_~\’        self.cond.notify()        self.cond.release()                            #g        print self.name + \’: 我赢了\’   #hclass Seeker(threading.Thread):    def __init__(self, cond, name):        super(Seeker, self).__init__()        self.cond = cond        self.name = name    def run(self):        self.cond.acquire()        self.cond.wait()    #a    #释放对琐的占用,同时线程挂起在这里,直到被notify并重新占有琐。                            #d        print self.name + \’: 我已经藏好了,你快来找我吧\’        self.cond.notify()        self.cond.wait()    #e                            #h        self.cond.release()        print self.name + \’: 被你找到了,哎~~~\’cond = threading.Condition()seeker = Seeker(cond, \’seeker\’)hider = Hider(cond, \’hider\’)seeker.start()hider.start()

执行结果如下:

123456 [root@361way condition]# python con3.pyhider: 我已经把眼睛蒙上了seeker: 我已经藏好了,你快来找我吧hider: 我找到你了 ~_~seeker: 被你找到了,哎~~~hider: 我赢了

便于对比,这里再给一个无限循环的例子。经典的生产者与消费者问题:假设有一群生产者(Producer)和一群消费者(Consumer)通过一个市场来交互产品。生产者的”策略“是如果市场上剩余的产品少于1000个,那么就生产100个产品放到市场上;而消费者的”策略“是如果市场上剩余产品的数量多余100个,那么就消费3个产品。

用Condition解决生产者与消费者问题的代码如下:

12345678910111213141516171819202122 import threadingimport timeclass Producer(threading.Thread):    def run(self):        global count        while True:            if con.acquire():                if count > 1000:                    con.wait()                else:                    count = 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


相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...