好了,因爲目前還沒有答案的,我不覺得太糟糕了這樣做。 雖然我在什麼是真正幕後發生的事情仍有意造成這個問題,我的最緊迫的問題是那些在更新2.指定的那些之中,子流程完成,但仍然沒有終止,造成僵局
什麼是JoinableQueue
和Manager().Queue()
之間的差異(和你應該什麼時候使用一個呢?)。重要的是,在這個例子中,替換另一個是否安全?
在下面的代碼中,我有一個簡單的進程池。每個進程通過進程隊列(pq
)拉從處理的數據,並且返回值隊列(rq
)來傳遞的處理的返回值返回到主線程。如果我不追加到返回值隊列中,它會起作用,但是一旦我這樣做了,出於某種原因阻止了進程停止。在這兩種情況下的過程run
方法返回,所以它不是put
在返回隊列阻塞,但在第二種情況下,過程本身不終止,所以程序死鎖當我join
上的進程。爲什麼會這樣?
更新:
它似乎有東西在隊列中的項目數。
在我的機器至少,我可以在隊列高達6570個項目和它的實際工作,但比這更多,它死鎖。它似乎與
Manager().Queue()
一起使用。
無論它是JoinableQueue
限制或只是我誤解了兩個對象之間的差異,我發現,如果我有一個Manager().Queue()
更換回隊列,它將按預期工作。它們之間有什麼區別,你應該什麼時候使用它們?如果我從
rq
OOP消費不會發生錯誤。這裏有一個答案,當我評論它時,它消失了。無論如何,它所說的一件事是質疑,如果我添加一個消費者,這個錯誤仍然會發生。我已經嘗試過了,答案是,沒有。它提到的另一件事是從the multiprocessing docs這句話作爲一個可能的關鍵問題。參照
JoinableQueue
的,它說:...用來計數的未完成任務數的旗語可 最終溢出引發異常。
import multiprocessing
class _ProcSTOP:
pass
class Proc(multiprocessing.Process):
def __init__(self, pq, rq):
self._pq = pq
self._rq = rq
super().__init__()
print('++', self.name)
def run(self):
dat = self._pq.get()
while not dat is _ProcSTOP:
# self._rq.put(dat) # uncomment me for deadlock
self._pq.task_done()
dat = self._pq.get()
self._pq.task_done()
print('==', self.name)
def __del__(self):
print('--', self.name)
if __name__ == '__main__':
pq = multiprocessing.JoinableQueue()
rq = multiprocessing.JoinableQueue()
pool = []
for i in range(4):
p = Proc(pq, rq)
p.start()
pool.append(p)
for i in range(10000):
pq.put(i)
pq.join()
for i in range(4):
pq.put(_ProcSTOP)
pq.join()
while len(pool) > 0:
print('??', pool)
pool.pop().join() # hangs here (if using rq)
print('** complete')
示例輸出,不使用回隊列:
++ Proc-1
++ Proc-2
++ Proc-3
++ Proc-4
== Proc-4
== Proc-3
== Proc-1
?? [<Proc(Proc-1, started)>, <Proc(Proc-2, started)>, <Proc(Proc-3, started)>, <Proc(Proc-4, started)>]
== Proc-2
?? [<Proc(Proc-1, stopped)>, <Proc(Proc-2, started)>, <Proc(Proc-3, stopped)>]
-- Proc-3
?? [<Proc(Proc-1, stopped)>, <Proc(Proc-2, started)>]
-- Proc-2
?? [<Proc(Proc-1, stopped)>]
-- Proc-1
** complete
-- Proc-4
示例輸出,使用返回隊列:
++ Proc-1
++ Proc-2
++ Proc-3
++ Proc-4
== Proc-2
== Proc-4
== Proc-1
?? [<Proc(Proc-1, started)>, <Proc(Proc-2, started)>, <Proc(Proc-3, started)>, <Proc(Proc-4, started)>]
== Proc-3
# here it hangs
可能是相關的:http://bugs.python.org/issue8237 – jfs
@ J.F.Sebastian。這可能是,但似乎是說,它阻止了'put',所有'run'的返回,並且'put'只在'run'內出現,所以我的'put'不能被阻止。 – tjm