下面是生产者消费者问题
生产者-消费者问题和Queue/queue模块
生产者生产商品,将商品放入到类似队列的数据结构中,生产的时间不确定
消费者消费商品,消费的时间不确定
使用Queue模块创建队列,生产者线程放入商品,消费者线程消费商品
下表列出Queue/queue模块的常用属性
属性 描述 Queue/queue模块的类 ****** Queue(maxsize=0) 创建一个先进先出队列,若给定最大值,则当队列没有空间时阻塞,否则为无限队列 LifoQueue(maxsize=0) 创建一个后进先出队列,若给定最大值,则空间满时阻塞,否则为无限队列 PriorityQueue(maxsize=0) 创建一个优先级队列,若给定最大值,当没有空间时阻塞,否则为无限队列 Queue/queue异常 Empty 当对空队列调用get*()方法时抛出的异常 Full 当对已满的队列调用put*()方法是抛出的异常 Queue/queue对象方法 qsize() 返回队列大小(该值为近似值) empty() 若队列为空,返回True,否则返回False full() 若队列为满,返回True,否则为False put(item,block=True,timeout=None) 将item放入队列,如果block为True且timeout=None,则在有可用之前阻塞,如果timeout为正值,则最多阻塞timeout秒,block=False,则抛出Empty异常 put_nowait(item) 和put(item,False)一样 get(block=True,timeout=None) 从队列中获得元素,若给定block则一直阻塞到有可用的元素为止 get_nowait() 和get(False)相同 task_done() 用于表示队列中的某个元素已执行完成,该方法会被下面的join()使用 join() 在队列中所有元素执行完毕并调用上面的task_done信号之前,保持阻塞
生产者消费者问题
from time import sleep,ctime import threading loops=(4,2) class MyThread(threading.Thread): def __init__(self,func,args,name=''): threading.Thread.__init__(self) self.func=func self.args=args self.name=name def run(self): return self.func(*self.args) def loop(nloop,nsec): print("loop {} started at {} ".format(nloop,ctime())) sleep(nsec) print("loop {} started at {} ".format(nloop,ctime())) def main(): print("Main started at {}".format(ctime())) threads=[] count=range(len(loops)) for i in count: t=MyThread(loop,(i,loops[i]),loop.__name__) threads.append(t) for i in count: threads[i].start() for i in count: threads[i].join() print("All done at {}".format(ctime())) if __name__ == '__main__': main() #——————————————上述为自定义的MyTread类,下面为生产者消费者问题—————————————————————— from time import ctime,sleep from random import randint from e import MyThread from queue import Queue def writeQ(queue): #将生产的对象放入队列中 print("Producing Q") queue.put("xxx",1) print("size now {}".format(queue.qsize())) def readQ(queue): #消费在队列中的对象 print("consuming Q size now {}".format(queue.qsize())) val=queue.get(1) def write(queue,loops): #根据loops生产随机数量的对象 for i in (range(loops)): writeQ(queue) sleep(randint(1,3)) def read(queue,loops): #根据loops消费随机数量的对象 for i in range(loops): readQ(queue) sleep(randint(2,5)) funcs=[write,read] nfuncs=range(len(funcs)) def main(): nloops=randint(2,5) #设置进行的随机次数 threads=[] q=Queue(32) #设置最大队列 for i in nfuncs: t=MyThread(funcs[i],(q,nloops),funcs[i].__name__) threads.append(t) for i in nfuncs: threads[i].start() for i in nfuncs: threads[i].join() print("All Done!!!") if __name__ == '__main__': main() '''显示结果如下: func write run at Sat May 23 08:19:39 2020 Producing Q size now 1 func read run at Sat May 23 08:19:39 2020 consuming Q size now 1 Producing Q size now 1 Producing Q size now 2 consuming Q size now 2 func write finished at Sat May 23 08:19:46 2020 consuming Q size now 1 func read finished at Sat May 23 08:19:51 2020 All Done!!!'''
- 注意不管是生产还是消费,每次只生产或消费一个对象
- 注意到write对象的暂停时间较短保证了消费时尽可能的可以拥有消费对象,而不是从空队列中取值
上述就是生产者消费者问题,希望对各位有所帮助!