【发布时间】:2019-06-28 04:10:54
【问题描述】:
首先,如果标题有点奇怪,我深表歉意,但我真的想不出如何将我面临的问题放在一行中。
所以我有以下代码
import time
from multiprocessing import Process, current_process, Manager
from multiprocessing import JoinableQueue as Queue
# from threading import Thread, current_thread
# from queue import Queue
def checker(q):
count = 0
while True:
if not q.empty():
data = q.get()
# print(f'{data} fetched by {current_process().name}')
# print(f'{data} fetched by {current_thread().name}')
q.task_done()
count += 1
else:
print('Queue is empty now')
print(current_process().name, '-----', count)
# print(current_thread().name, '-----', count)
if __name__ == '__main__':
t = time.time()
# m = Manager()
q = Queue()
# with open("/tmp/c.txt") as ifile:
# for line in ifile:
# q.put((line.strip()))
for i in range(1000):
q.put(i)
time.sleep(0.1)
procs = []
for _ in range(2):
p = Process(target=checker, args=(q,), daemon=True)
# p = Thread(target=checker, args=(q,))
p.start()
procs.append(p)
q.join()
for p in procs:
p.join()
示例输出
1:当进程刚刚挂起时
Queue is empty now
Process-2 ----- 501
output hangs at this point
2:当一切正常时。
Queue is empty now
Process-1 ----- 515
Queue is empty now
Process-2 ----- 485
Process finished with exit code 0
现在这种行为是间歇性的,有时会发生,但并非总是如此。
我也尝试使用Manager.Queue() 来代替multiprocessing.Queue(),但没有成功,并且都出现了同样的问题。
我用multiprocessing 和multithreading 对此进行了测试,我得到了完全相同的行为,与multithreading 相比,与multiprocessing 相比,这种行为的发生率要低得多。
所以我认为我在概念上遗漏了一些东西或做错了,但我现在无法抓住它,因为我在这方面花费了太多时间,现在我的脑海中没有看到可能非常基本的东西。
感谢您的帮助。
【问题讨论】:
-
显然如果在队列
q为空之前调用join(),可能会出现死锁:stackoverflow.com/questions/31665328/… -
即使我在加入进程之前添加了
q.join(),它仍然无法按预期工作。 -
可能是因为
multiprocessing.Queue没有任何名为join()的方法。来自文档:Queue implements all the methods of queue.Queue except for task_done() and join().第一个“队列”是指您在上面的示例中使用的multiprocessing.Queue。 -
我试过
JoinabaleQueue -
@TuanDT 供您参考刚刚更新了问题。