普通生产者与消费者模式
import threading
import random,time
Item = 1000
lock = threading.Lock()
class Producter(threading.Thread):
def run(self):
global Item
while(True):
time.sleep(0.5)
c = random.randint(100,1000)
lock.acquire()
Item += c
print("{} 产生{} 现存{}".format(threading.current_thread(),c,Item))
lock.release()
class Consumer(threading.Thread):
def run(self):
global Item
while(True):
time.sleep(0.5)
c = random.randint(100,1000)
if(c > Item):
print("ERROR {}消费{} 现存{}".format(threading.current_thread(),c,Item))
continue
else:
lock.acquire()
Item -=c
print("{} 消费{} 现存{}".format(threading.current_thread(),c,Item))
lock.release()
def main():
for i in range(3):
t = Consumer(name="消费者{}".format(i))
t.start()
for i in range(5):
t = Producter(name="生产者{}".format(i))
t.start()
if __name__ == '__main__':
main()
Condition版生产者消费者
Condition(条件变量)通常与一个锁关联。需要在多个Contidion中共享一个锁时,可以传递一个Lock/RLock实例给构造方法,否则它将自己生成一个RLock实例。可以认为,除了Lock带有的锁定池外,Condition还包含一个等待池,池中的线程处于状态图中的等待阻塞状态,直到另一个线程调用notify()/notifyAll()通知;得到通知后线程进入锁定池等待锁定。
- acquire(): 获得线程锁
- release(): 释放锁
- wait(timeout): 线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。
- notify(n=1): 通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notify()不会主动释放Lock。
- notifyAll(): 如果wait状态线程比较多,notifyAll的作用就是通知所有线程
Item = 1000
cond = threading.Condition()
class Producter(threading.Thread):
def run(self):
global Item
while(True):
time.sleep(0.5)
c = random.randint(100,1000)
cond.acquire()
Item += c
print("{} 产生{} 现存{}".format(threading.current_thread(),c,Item))
cond.notify_all()
cond.release()
class Consumer(threading.Thread):
def run(self):
global Item
while(True):
time.sleep(0.5)
cond.acquire()
c = random.randint(100,1000)
while(c > Item):
print("ERROR {}消费{} 现存{}".format(threading.current_thread(),c,Item))
cond.wait()
Item -= c
print("{} 消费{} 现存{}".format(threading.current_thread(), c, Item))
cond.release()
def main():
for i in range(3):
t = Consumer(name="消费者{}".format(i))
t.start()
for i in range(5):
t = Producter(name="生产者{}".format(i))
t.start()
if __name__ == '__main__':
main()