python 多进程并发 阻塞_python多进程并发和多线程并发

from multiprocessing importJoinableQueue,Process,current_processdefconsumer(jq,name):whileTrue:

word=jq.get()print('%s 取到了%s'%(name,word))

jq.task_done()#print(jq.task_done())

defprint_word(jq,produce_name):for c in [chr(ord('A')+i) for i in range(26)]:

jq.put(c)print("%s 生产了一个 %s"%(produce_name,c))

jq.join()if __name__ == '__main__':

jq= JoinableQueue() #不管用什么队列,都必须要先实例化

produce_name = 'admin'

#consumer_list = ['kobe','t-mac']

pn = Process(target=print_word,args=(jq,produce_name))

tt1= Process(target=consumer, args=(jq,'kobe'))

tt2= Process(target=consumer, args=(jq,'t-mac'))

tt1.daemon=True

tt2.daemon=True

tt1.start()

tt2.start()

pn.start()

pn.join()'''使用JoinableQueue实现多线程搞得时候要注意这几个方法的关联

1.pn.join() 为什么子线程pn要设置阻塞?

首先要知道join方法是Process提供来管理子进程的,在同步阻塞的时候,只关心子线程是否执行完毕,只要子线程结束,才会执行阻塞后的代码

2.jq.join()为什么子进程设置阻塞?

因为jq要等待consumer方法将全部的字母取走,只要consumer将全部的字母取走之后,jq才不阻塞了,代表着print_word方法已经将工作做完了

jq.join()在这里可以理解成:当队列为空我才不阻塞了,

3.jq.task_done()是什么意思?

通知producer里面的jq.join(),要将队列里面的计数器-1,因为有一个数据被取走了,当所有的任务处理完之后,队列的计数器为0

也就是队列为空了,这是jq.join()就不阻塞了

4.那tt1.daemon =True和tt2.daemon =True子进程为什么要设置成守护进程?

我们子啊consumer里面写的是while True,理解是这个死循环永远不能退出

但是守护进程会随着主进程的运行完毕之后跟着结束,我们退出不了while,那把主进程kill掉,也就退出了死循环

所以:

pn.join()在等待这自己的子进程函数print_word执行完毕,因为执行到主线程搞得代码结束为止,所以主线程退出

但是print_word()子线程里面的jq.join()也在阻塞这,等待jq.task_done()发过来的最后一个信号,也就是队列为空

所以,当jq.task_done()发空信号之后jq.join()不阻塞,然后pn.join()不阻塞,程序结束

而进程中的守护进程的特点是随着主进程的结束而结束,所以整个程序结束,name死循环也就结束了。

理解task_done():

如果进程或线程每从队列里取一次,但没有执行task_done(),则join无法判断队列到底有没有结束,在最后执行个join()是等不到结果的,会一直挂起。

可以理解为,每task_done一次 就从队列里删掉一个元素,这样在最后join的时候根据队列长度是否为零来判断队列是否结束,从而执行主线程。'''

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值