因为刚好在学习线程 队列Queue的过程中发现了 队列中的 .join() 和 .task_done()
查看官方的源码得到注释:
task_done():
表示当前队列的任务已经完成!
对于每个用于获取任务的get(),对task_done()的后续调用告诉队列任务完成了。 注释:相当于会返回!再不断的循环调用中会直接返回!
如果join()当前正在阻塞,则当所有项已被处理(意味着接收到task_done()调用对于已放入队列中的每个项目)。
如果调用次数超过项的次数,则引发ValueError 在队列中。
join():
阻塞,直到队列中的所有项目都已获取和处理。
每当项目添加到排队。每当使用者线程调用task_ done()时,计数就会减少 以指示已检索到该项,并且该项上的所有工作都已完成。
当未完成任务的计数降至零时,join()将取消阻止。 # 很简单就相当于阻塞 ,知道task_done()返回0 的时候就取消阻止
我试着用最简单的代码来解释:
1 import time 2 import threading 3 from queue import Queue 4 5 def set_value(q): 6 7 for x in range(5): 8 q.put(x) 9 10 time.sleep(1) 11 12 13 14 def get_value(q): 15 while True: 16 time.sleep(2) 17 if q.empty(): 18 break 19 # print(q.get()) 20 item = q.get() 21 print(item) 22 q.task_done() # 注释状况下程序不会停止,因为join阻塞这一直在等他!! 23 return 24 25 26 def main(): 27 q = Queue(4) 28 t1 = threading.Thread(target=set_value,args=(q,)) 29 t2 = threading.Thread(target=get_value, args=(q,)) 30 t1.start() 31 t2.start() 32 q.join() 33 print("谁能阻塞我?") 34 35 36 if __name__ == '__main__': 37 main()
简单解释一下,我一个线程写,一个线程读,同时进行,然后我一开始start()之后就 阻塞join了
一共写了5次,所以每一次读取 应该取出5次后就取完了讲道理 while 的break的条件成立了!退出while后应该没运行了
这里就是join()的作用了,他没有收到 队列为空的响应! 所以我这里如果 在每次get()后面都进行一次 task_done() (这里相当于一次 是否还阻塞的判断)
成功取出所有值后 task_done() 就返回给 join()!!!
ok!!vans大吉我们这样就可以确保所有值取到 不阻塞这个线程了,继续下面的其他操作!