记得学操作系统这门课的时候就打算自己写一个,居然一眨眼过了一年才写,真是对不起老师阿!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#coding=utf-8
'''
Created on 2013年11月13日
生产者与消费者python版
@author: dear_shen
'''
import threading
import Queue
import time
condition = threading.Condition() #设置条件变量
class Producter(threading.Thread):
def __init__(self,puc_pool,i):
threading.Thread.__init__(self)
self.puc_pool = puc_pool
self.setName("生产者"+str(i))
def run(self):
while True:
if condition.acquire():
if self.puc_pool.qsize() < 10:
print "%s 开始生产产品 %s" % (self.name,self.puc_pool.qsize()+1)
self.puc_pool.put(self.name+"-"+str(self.puc_pool.qsize()+1))
condition.notify() #唤醒阻塞的线程
else:
print "产品数量多于10个,停止生产,生产者休息!"
condition.wait() #阻塞自己
condition.release()
time.sleep(1)
class Consumer(threading.Thread):
def __init__(self,puc_pool,i):
threading.Thread.__init__(self)
self.puc_pool = puc_pool
self.setName("消费者"+str(i))
def run(self):
while True:
if condition.acquire():
if self.puc_pool.qsize()>0:
tem = self.puc_pool.get()
print "%s 使用了产品 %s,还剩%s个" % (self.name,tem,self.puc_pool.qsize())
self.puc_pool.task_done() #产品队列中减少一个
condition.notify()
else:
print "没有产品了,消费者休息!"
condition.wait()
condition.release()
time.sleep(2)
if __name__ == "__main__":
print "main begin"
puc = Queue.Queue()
for i in range(2):
p = Producter(puc,i)
p.setDaemon(True)
p.start()
time.sleep(5)
for i in range(5):
c = Consumer(puc,i)
c.setDaemon(True)
c.start()
puc.join()#当产品队列为空时候再打印main over,如果注释掉了上面的setDaemon,虽然打印了main over,但是子线程并没有结束。
print "main over"

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
main begin
生产者0 开始生产产品 1
生产者1 开始生产产品 2
生产者0 开始生产产品 3
生产者1 开始生产产品 4
生产者0 开始生产产品 5
生产者1 开始生产产品 6
生产者0 开始生产产品 7
生产者1 开始生产产品 8
生产者0 开始生产产品 9
生产者1 开始生产产品 10
产品数量多于10个,停止生产,生产者休息!
消费者0 使用了产品 生产者0-1,还剩9个
生产者0 开始生产产品 10
消费者1 使用了产品 生产者1-2,还剩9个
消费者2 使用了产品 生产者0-3,还剩8个
消费者3 使用了产品 生产者1-4,还剩7个
消费者4 使用了产品 生产者0-5,还剩6个
生产者0 开始生产产品 7
生产者1 开始生产产品 8
消费者0 使用了产品 生产者1-6,还剩7个
消费者4 使用了产品 生产者0-7,还剩6个
消费者2 使用了产品 生产者1-8,还剩5个
消费者1 使用了产品 生产者0-9,还剩4个
消费者3 使用了产品 生产者1-10,还剩3个
生产者0 开始生产产品 4
生产者1 开始生产产品 5
生产者0 开始生产产品 6
生产者1 开始生产产品 7
消费者0 使用了产品 生产者0-10,还剩6个
消费者4 使用了产品 生产者0-7,还剩5个
消费者2 使用了产品 生产者1-8,还剩4个
消费者3 使用了产品 生产者0-4,还剩3个
消费者1 使用了产品 生产者1-5,还剩2个
生产者0 开始生产产品 3
生产者1 开始生产产品 4
生产者0 开始生产产品 5
生产者1 开始生产产品 6
消费者4 使用了产品 生产者0-6,还剩5个
消费者0 使用了产品 生产者1-7,还剩4个
消费者3 使用了产品 生产者0-3,还剩3个
消费者2 使用了产品 生产者1-4,还剩2个
消费者1 使用了产品 生产者0-5,还剩1个
生产者1 开始生产产品 2
生产者0 开始生产产品 3
生产者1 开始生产产品 4
生产者0 开始生产产品 5
消费者4 使用了产品 生产者1-6,还剩4个
消费者0 使用了产品 生产者1-2,还剩3个
消费者1 使用了产品 生产者0-3,还剩2个
消费者3 使用了产品 生产者1-4,还剩1个
生产者0 开始生产产品 2
生产者1 开始生产产品 3
消费者2 使用了产品 生产者0-5,还剩2个
生产者0 开始生产产品 3
生产者1 开始生产产品 4
消费者4 使用了产品 生产者0-2,还剩3个
消费者3 使用了产品 生产者1-3,还剩2个
消费者1 使用了产品 生产者0-3,还剩1个
消费者0 使用了产品 生产者1-4,还剩0个
main over

因为使用了setDaemon(True),所以看不见消费者else分支的输出,想看效果的话把其改成False即可。