दरअसल, यहां तक कि जब pool
वस्तु के लिए सभी उपयोगकर्ता संदर्भ हटा दिए जाते हैं, और कोई कार्य कतार कोड में हैं, और सब कचरा संग्रहण किया जाता है, तो अभी भी प्रक्रियाओं रहने के रूप में व्यर्थ लाश ऑपरेटिंग सिस्टम में - प्लस हम 3 ज़ोंबी सेवा धागे Pool
फांसी (अजगर 2.7 और 3.4) से है:
>>> del pool
>>> gc.collect()
0
>>> gc.garbage
[]
>>> threading.enumerate()
[<_MainThread(MainThread, started 5632)>, <Thread(Thread-8, started daemon 5252)>,
<Thread(Thread-9, started daemon 5260)>, <Thread(Thread-7, started daemon 7608)>]
और आगे Pool()
के अधिक से अधिक प्रक्रिया जोड़ सकते हैं और लाश थ्रेड ... जो जब तक मुख्य प्रक्रिया समाप्त होता है रहना होगा ।
यह ज़ोंबी पूल को रोकने के लिए एक विशेष प्रहार की आवश्यकता है - अपनी सेवा धागा _handle_workers
के माध्यम से:
>>> ths = threading.enumerate()
>>> for th in ths:
... try: th.name, th._state, th._Thread__target
... except AttributeError: pass
...
('MainThread', 1, None)
('Thread-8', 0, <function _handle_tasks at 0x01462A30>)
('Thread-9', 0, <function _handle_results at 0x014629F0>)
('Thread-7', 0, <function _handle_workers at 0x01462A70>)
>>> ths[-1]._state = multiprocessing.pool.CLOSE # or TERMINATE
>>> threading.enumerate()
[<_MainThread(MainThread, started 5632)>]
>>>
अन्य सेवा धागे समाप्त हो जाता है यही कारण है कि और भी बच्चे प्रक्रियाओं समाप्त हो जाता है।
मुझे लगता है कि एक समस्या है, वहाँ अजगर पुस्तकालय में एक संसाधन रिसाव बग, weakref
की का सही उपयोग द्वारा निर्धारित किया जा सकता है जो है।
अन्य मुद्दा यह है कि Pool
निर्माण & समाप्ति महंगा है (पूल प्रति 3 सेवा धागे सिर्फ प्रबंधन के लिए सहित!), और वहाँ ususually सीपीयू कोर की तुलना में अधिक कार्यकर्ता प्रक्रियाओं (उच्च CPU लोड होता है) के लिए कोई कारण नहीं है या किसी सीमित सीमित संसाधन (जैसे नेटवर्क बैंडविड्थ) के अनुसार सीमित संख्या से अधिक। तो एक पूल को एक सिंगलुलर ऐप ग्लोबल रिसोर्सेज (वैकल्पिक रूप से टाइमआउट द्वारा प्रबंधित) की तरह एक क्लोजर (या एक समाप्त() - बग के कारण कामकाज के बजाय एक पूल के इलाज के लिए उचित है।
उदाहरण के लिए:
try:
_unused = pool # reload safe global var
except NameError:
pool = None
def get_pool():
global pool
if pool is None:
atexit.register(stop_pool)
pool = Pool(CPUCORES)
return pool
def stop_pool():
global pool
if pool:
pool.terminate()
pool = None
आप दे सकते हैं क्या '' ... अपने 'pool.map (...)' के अंदर है के बारे में एक संकेत है? – SingleNegationElimination
निश्चित रूप से। '... 'केवल पढ़ने योग्य हैं लेकिन' वाष्पशील 'ऑब्जेक्ट के सदस्य चर पर CPU-भारी संचालन। मैं प्रदर्शन को बेहतर बनाने के लिए समानांतर में निष्पादित करना चाहता हूं। वस्तु 'do_stuff' की अवधि के लिए उत्परिवर्तित नहीं है। – user124114