python threading_python threading之Condition

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

thread-condition.png

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

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

thread-talk.png

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

#coding:utf-8

#---- Condition

#---- 捉迷藏的游戏

import threading, time

class 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 + ': 我赢了' #h

class 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()

执行结果如下:

[root@361way condition]# python con3.py

hider: 我已经把眼睛蒙上了

seeker: 我已经藏好了,你快来找我吧

hider: 我找到你了 ~_~

seeker: 被你找到了,哎~~~

hider: 我赢了

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

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 = 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 = 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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值