假设我有一个线程池。此线程池使用两个队列q1
和q2
。它从q1
读取并在q2
上写入新项目。当q1
为空时,我们交换两个队列q1, q2, = q2, q1
并重复此过程,直到两个队列为空。为了同步线程,我使用另一个只包含一个项目的队列,并在流程结束时删除此项目。
我认为这是一种非常愚蠢的方法。有任何改进建议吗?
一个非常好的简单示例在docs上,但只有一个队列。如果它是正确的,我的解决方案看起来不太好:
global flag
global lock
global barrier
global q1
global q2
global q
while True:
if q1.empty():
flag = False
barrier.wait() # wait for all the theads to reach this point.
# execute the code of swapping queues only once
with lock:
if not flag:
flag = True
if q2.empty():
q.get()
q.task_done()
else:
q1, q2 = q2, q1
process_items_in_q1()
答案 0 :(得分:0)
我认为你的方法有效。以下是您可能会或可能不会找到更好的其他两个:
您只能使用一个队列并按N个标记来分隔“级别”,其中N是线程数。当一个线程读取一个标记时,它只调用barrier.wait()。如果目标只是确保所有N个线程在级别之间调用barrier.wait(),那么这应该足够了。
或者,您可以简化上面发布的代码:使用2个普通列表而不是2个队列。所有线程都从list1
弹出并附加到list2
,这不需要在Queue逻辑中特别小心。此外,如果“级别”各自相对较大,您可以简单地为每个级别重复创建线程的整个代码,并等待它们全部完成。这将使一级一级逻辑更加明显。
(最后,像往常一样,请注意到目前为止你没有通过在Python中使用线程获得任何处理能力:有GIL。)