Python学习(三):生产者-消费者
为了学习Python,最好还是直接从写代码入手,解决的问题如下:
1、设计三个线程,线程1每秒钟对一个值进行+1操作,线程2每秒钟对该值进行+3操作,线程3每秒钟对该值进行-2操作
涉及知识点:线程,锁,time标准库
代码如下:
#coding=utf-8
'''
Created on 2015年8月19日
设计三个线程,线程1每秒钟对一个值进行+1操作,线程2每秒钟对该值进行+3操作,线程3每秒钟对该值进行-2操作
@author: minmin
'''
import time
import thread
def loop(name, value, nsleep, action, lock1, lock2):
while True:
lock1.acquire()
value[0] += action
action_str = ""
if action >= 0:
action_str = "+" + str(action)
else:
action_str = str(action)
print name + "对value做了" + action_str + "操作, value = " + str(value[0])
lock1.release()
time.sleep(nsleep)
lock2.release()
def main():
lock = thread.allocate_lock()
lock1 = thread.allocate_lock()
lock2 = thread.allocate_lock()
lock3 = thread.allocate_lock()
value = [10]
lock1.acquire()
lock2.acquire()
lock3.acquire()
locks = [lock1, lock2, lock3]
thread.start_new_thread(loop, ("Producer1", value, 1, 1, lock, lock1))
thread.start_new_thread(loop, ("Producer2", value, 1, 3, lock, lock2))
thread.start_new_thread(loop, ("Customer1", value, 1, -2, lock, lock3))
#防止主线程执行完自动关闭运行的三个线程
for i in locks:
while i.locked(): pass
if __name__ == '__main__':
main()
运行结果如下图:
2、设计三个线程,两个生产者一个消费者:一个生产者每秒钟生产1一个产品放入产品池,一个生产者每秒钟生产2个产品放入产品池,一个消费者每秒钟从产品池中消费1-5之间的一个随机数个产品。产品池满时,生产者等待,产品池有空位时,生产者继续生产;产品池空时,消费者等待,产品池有产品时,消费者继续消费。每个产品有自己独特的标记。
涉及知识点:多线程、锁、threading、生产者-消费者、阻塞队列。
这里先实现一个线程的子模块myThread,方便调用函数。
代码如下:
#coding=utf-8
'''
Created on 2015年8月23日
@author: minmin
'''
import threading
import time
class MyThread(threading.Thread):
def __init__(self, func, args, name = ''):
threading.Thread.__init__(self)
self.func = func
self.args = args
self.name = name
def getResult(self):
return self.res
def run(self):
print 'starting %s at:%s' % (self.name, time.strftime('%Y-%m-%d %H:%M:%S'))
self.res = apply(self.func, self.args)
print '%s finished at:%s' % (self.name, time.strftime('%Y-%m-%d %H:%M:%S'))
生产者-消费者代码如下:
#coding=utf-8
'''
Created on 2015年8月23日
@author: minmin
'''
import random
import time
import myThread
import Queue
import threading
'''
生产者,每nsleep秒生产nprod个产品,放入queue中
a 产品标记
name 生产者的名字
'''
def producer(queue, nsleep, nprod, name, a, lock):
while True:
for i in range(nprod):
lock.acquire()
queue.put(a[0], 1)
print '%s生产了一个产品:%d, 当前队列大小:%d' % (name, a[0], queue.qsize())
a[0] += 1
lock.release()
time.sleep(nsleep)
'''
消费着,每nsleep秒从queue中消费minProd至maxProd间随机产生的一个值的产品
name 消费者的名字
'''
def consumer(queue, nsleep, minProd, maxProd, name):
while True:
nprod = random.randint(minProd, maxProd)
for i in range(nprod):
val = queue.get(1)
print '%s消费了一个产品:%d, 当前队列大小:%d' % (name, val, queue.qsize())
time.sleep(nsleep)
def main():
queue = Queue.Queue(10)
a = [0]
lock = threading.Lock()
producer1 = myThread.MyThread(producer, (queue, 1, 1, 'producer1', a, lock), 'producer1')
producer2 = myThread.MyThread(producer, (queue, 1, 2, 'producer2', a, lock), 'producer2')
consumer1 = myThread.MyThread(consumer, (queue, 1, 1, 5, 'consumer1'), 'consumer1')
threads = [producer1, producer2, consumer1]
for i in threads:
i.start()
for i in threads:
i.join()
if __name__ == '__main__':
main()
运行结果如下:
代码我也放到GitHub上面了