ठीक है, क्योंकि वर्तमान में कोई जवाब नहीं है, मुझे ऐसा करने में बहुत बुरा नहीं लगता है। जब मैं इस समस्या का कारण करने के लिए अभी भी क्या वास्तव में पर्दे के पीछे क्या हो रहा है में दिलचस्पी रखता हूँ, मेरी सबसे जरूरी सवाल उन अद्यतन 2 में निर्दिष्ट कर रहे हैं उन जा रहा है,सबप्रोसेस पूर्ण हो जाता है लेकिन अभी भी समाप्त नहीं होता है, जिससे डेडलॉक
क्या एक JoinableQueue
और एक Manager().Queue()
के बीच मतभेद रहे हैं (और आप दूसरे पर एक का उपयोग कब करना चाहिए?)। और महत्वपूर्ण बात यह है कि, इस उदाहरण में, दूसरे के लिए एक को बदलने के लिए सुरक्षित है?
निम्नलिखित कोड में, मेरे पास एक सरल प्रक्रिया पूल है। प्रत्येक प्रक्रिया को प्रोसेस क्यूई (pq
) से संसाधित करने के लिए डेटा को खींचने के लिए, और रिटर्न-वैल्यू कतार (rq
) को प्रोसेस के लौटाए गए मानों को मुख्य थ्रेड पर वापस करने के लिए पारित किया जाता है। अगर मैं रिटर्न-वैल्यू कतार में शामिल नहीं हूं तो यह काम करता है, लेकिन जैसे ही मैं करता हूं, किसी कारण से प्रक्रियाओं को रोकने से अवरुद्ध कर दिया जाता है। दोनों मामलों में प्रक्रिया run
विधियों की वापसी होती है, इसलिए यह वापसी-कतार अवरोधन पर put
नहीं है, लेकिन दूसरे मामले में प्रक्रियाएं स्वयं समाप्त नहीं होती हैं, इसलिए प्रक्रियाओं पर join
जब प्रोग्राम deadlocks। यह क्यों होगा?
अपडेट:
यह कतार में आइटम्स की संख्या के साथ के लिए कुछ है लगता है।
कम से कम मेरी मशीन पर, मेरे पास कतार में 6570 आइटम हो सकते हैं और यह वास्तव में काम करता है, लेकिन इससे भी अधिक और यह deadlocks।यह
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
@ जेएफ। सेबेस्टियन। ऐसा हो सकता है लेकिन यह है कि यह कहते हुए किया जाना है कि यह ब्लॉक से पहले अपने सभी 'run' के return'' put' पर अवरोधित कर रही है, और 'put' केवल' run' भीतर तो मेरी 'put' की नहीं कर सकते हैं उत्पन्न कर रहा है लगता है अवरुद्ध होना – tjm