JoinableQueue同样通过multiprocessing使用。
创建队列的另外一个类:
JoinableQueue([maxsize]):这就像是一个Queue对象,但队列允许项目的使用者通知生成者项目已经被成功处理。通知进程是使用共享的信号和条件变量来实现的。
参数介绍:
maxsize是队列中允许最大项数,省略则无大小限制。
方法介绍:
JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常
q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
示例1:
from multiprocessing import Process,JoinableQueue import time,random def consumer(q): while True: time.sleep(random.randint(1,5)) res=q.get() print('消费者拿到了 %s' %res) q.task_done() def producer(seq,q): for item in seq: time.sleep(random.randrange(1,2)) q.put(item) print('生产者做好了 %s' %item) q.join() if __name__ == '__main__': q=JoinableQueue() seq=('包子%s' %i for i in range(10)) p=Process(target=consumer,args=(q,)) p.daemon=True #设置为守护进程,在主线程停止时p也停止,但是不用担心,producer内调用q.join保证了consumer已经处理完队列中的所有元素 p.start() producer(seq,q) print('主线程')
示例2:
from multiprocessing import Process,JoinableQueue import time,random def consumer(name,q): while True: time.sleep(random.randint(1,2)) res=q.get() print('\033[45m%s拿到了 %s\033[0m' %(name,res)) q.task_done() def producer(seq,q): for item in seq: time.sleep(random.randrange(1,2)) q.put(item) print('\033[46m生产者做好了 %s\033[0m' %item) q.join() if __name__ == '__main__': q=JoinableQueue() seq=('包子%s' %i for i in range(10)) p1=Process(target=consumer,args=('消费者1',q,)) p2=Process(target=consumer,args=('消费者2',q,)) p3=Process(target=consumer,args=('消费者3',q,)) p1.daemon=True p2.daemon=True p3.daemon=True p1.start() p2.start() p3.start() producer(seq,q) print('主线程')
示例3:
from multiprocessing import Process,JoinableQueue import time,random def consumer(name,q): while True: # time.sleep(random.randint(1,2)) res=q.get() print('\033[45m%s拿到了 %s\033[0m' %(name,res)) q.task_done() def producer(seq,q): for item in seq: # time.sleep(random.randrange(1,2)) q.put(item) print('\033[46m生产者做好了 %s\033[0m' %item) q.join() if __name__ == '__main__': q=JoinableQueue() seq=['包子%s' %i for i in range(10)] #在windows下无法传入生成器,我们可以用列表解析测试 p1=Process(target=consumer,args=('消费者1',q,)) p2=Process(target=consumer,args=('消费者2',q,)) p3=Process(target=consumer,args=('消费者3',q,)) p1.daemon=True p2.daemon=True p3.daemon=True p1.start() p2.start() p3.start() # producer(seq,q) #也可以是下面三行的形式,开启一个新的子进程当生产者,不用主线程当生产者 p4=Process(target=producer,args=(seq,q)) p4.start() p4.join() print('主线程')