मैं एक साधारण पायथन थ्रेड पूल पैटर्न के अच्छे कार्यान्वयन के आसपास देख रहा हूं और वास्तव में मेरी ज़रूरतों के अनुरूप कुछ भी नहीं ढूंढ सकता। मैं अजगर 2.7 का उपयोग कर रहा हूं और मैंने पाया है कि सभी मॉड्यूल या तो काम नहीं करते हैं, या श्रमिकों में अपवादों को ठीक से संभाल नहीं करते हैं। मैं सोच रहा था कि अगर कोई ऐसी लाइब्रेरी के बारे में जानता है जो उस प्रकार की कार्यक्षमता प्रदान कर सकता है जिसे मैं खोज रहा हूं। बहुत सराहना में मदद करें।पाइथन थ्रेड पूल जो अपवादों को संभालता है
Multiprocessing
मेरे पहले प्रयास के साथ था निर्मित multiprocessing
मॉड्यूल है, लेकिन इस धागे लेकिन subprocesses उपयोग नहीं करता है के रूप में के बजाय हम इस समस्या वस्तुओं है कि मसालेदार नहीं किया जा सकता में चलाने। यहाँ नहीं जाओ
from multiprocessing import Pool
class Sample(object):
def compute_fib(self, n):
phi = (1 + 5**0.5)/2
self.fib = int(round((phi**n - (1-phi)**n)/5**0.5))
samples = [Sample() for i in range(8)]
pool = Pool(processes=8)
for s in samples: pool.apply_async(s.compute_fib, [20])
pool.join()
for s in samples: print s.fib
# PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
वायदा
तो मैं देख रहा हूँ अजगर 3.2 here की ठंडी समवर्ती सुविधाओं में से कुछ की एक पीठ बंदरगाह है। यह उपयोग करने के लिए सही और सरल लगता है। समस्या यह है कि जब आप किसी एक श्रमिक में अपवाद प्राप्त करते हैं, तो आपको केवल "ज़ीरोडिविजन एरर" जैसे अपवाद का प्रकार मिलता है लेकिन कोई ट्रेसबैक नहीं होता है और इस प्रकार किसी भी संकेत का कोई संकेत अपवाद का कारण नहीं बनता है। कोड डीबग करना असंभव हो जाता है। नही जाओ।
from concurrent import futures
class Sample(object):
def compute_fib(self, n):
phi = (1 + 5**0.5)/2
1/0
self.fib = int(round((phi**n - (1-phi)**n)/5**0.5))
samples = [Sample() for i in range(8)]
pool = futures.ThreadPoolExecutor(max_workers=8)
threads = [pool.submit(s.compute_fib, 20) for s in samples]
futures.wait(threads, return_when=futures.FIRST_EXCEPTION)
for t in threads: t.result()
for s in samples: print s.fib
# futures-2.1.3-py2.7.egg/concurrent/futures/_base.pyc in __get_result(self)
# 354 def __get_result(self):
# 355 if self._exception:
#--> 356 raise self._exception
# 357 else:
# 358 return self._result
#
# ZeroDivisionError: integer division or modulo by zero
WorkerPool
मैं इस पैटर्न here का एक अन्य कार्यान्वयन पाया। इस बार जब कोई अपवाद होता है तो यह मुद्रित होता है, लेकिन फिर मेरा आईपीथॉन इंटरैक्टिव दुभाषिया एक लटकते राज्य में छोड़ा जाता है और उसे दूसरे खोल से मारने की आवश्यकता होती है। नही जाओ।
import workerpool
class Sample(object):
def compute_fib(self, n):
phi = (1 + 5**0.5)/2
1/0
self.fib = int(round((phi**n - (1-phi)**n)/5**0.5))
samples = [Sample() for i in range(8)]
pool = workerpool.WorkerPool(size=8)
for s in samples: pool.map(s.compute_fib, [20])
pool.wait()
for s in samples: print s.fib
# ZeroDivisionError: integer division or modulo by zero
# ^C^C^C^C^C^C^C^C^D^D
# $ kill 1783
ThreadPool
फिर भी एक अन्य कार्यान्वयन here। इस बार जब कोई अपवाद होता है, तो यह stderr
पर मुद्रित होता है लेकिन स्क्रिप्ट को बाधित नहीं किया जाता है और इसके बजाय निष्पादन जारी रहता है, जो अपवाद के उद्देश्य को रोकता है और चीजों को असुरक्षित बना सकता है। अभी भी प्रयोग योग्य नहीं है।
import threadpool
class Sample(object):
def compute_fib(self, n):
phi = (1 + 5**0.5)/2
1/0
self.fib = int(round((phi**n - (1-phi)**n)/5**0.5))
samples = [Sample() for i in range(8)]
pool = threadpool.ThreadPool(8)
requests = [threadpool.makeRequests(s.compute_fib, [20]) for s in samples]
requests = [y for x in requests for y in x]
for r in requests: pool.putRequest(r)
pool.wait()
for s in samples: print s.fib
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
# ZeroDivisionError: integer division or modulo by zero
#---> 17 for s in samples: print s.fib
#
#AttributeError: 'Sample' object has no attribute 'fib'
- अपडेट -
ऐसा लगता है कि futures
पुस्तकालय के विषय में, अजगर 3 के व्यवहार अजगर 2.
futures_exceptions.py
के समान नहीं है:
from concurrent.futures import ThreadPoolExecutor, as_completed
def div_zero(x):
return x/0
with ThreadPoolExecutor(max_workers=4) as executor:
futures = executor.map(div_zero, range(4))
for future in as_completed(futures): print(future)
अजगर 2.7.6 आउटपुट:
Traceback (most recent call last):
File "...futures_exceptions.py", line 12, in <module>
for future in as_completed(futures):
File "...python2.7/site-packages/concurrent/futures/_base.py", line 198, in as_completed
with _AcquireFutures(fs):
File "...python2.7/site-packages/concurrent/futures/_base.py", line 147, in __init__
self.futures = sorted(futures, key=id)
File "...python2.7/site-packages/concurrent/futures/_base.py", line 549, in map
yield future.result()
File "...python2.7/site-packages/concurrent/futures/_base.py", line 397, in result
return self.__get_result()
File "...python2.7/site-packages/concurrent/futures/_base.py", line 356, in __get_result
raise self._exception
ZeroDivisionError: integer division or modulo by zero
अजगर 3.3.2 उत्पादन:
Traceback (most recent call last):
File "...futures_exceptions.py", line 11, in <module>
for future in as_completed(futures):
File "...python3.3/concurrent/futures/_base.py", line 193, in as_completed
with _AcquireFutures(fs):
File "...python3.3/concurrent/futures/_base.py", line 142, in __init__
self.futures = sorted(futures, key=id)
File "...python3.3/concurrent/futures/_base.py", line 546, in result_iterator
yield future.result()
File "...python3.3/concurrent/futures/_base.py", line 392, in result
return self.__get_result()
File "...python3.3/concurrent/futures/_base.py", line 351, in __get_result
raise self._exception
File "...python3.3/concurrent/futures/thread.py", line 54, in run
result = self.fn(*self.args, **self.kwargs)
File "...futures_exceptions.py", line 7, in div_zero
return x/0
ZeroDivisionError: division by zero
यह पूरी तरह से अस्थायी रूप से करने के लिए एक फोन के साथ 'pool.map' करने के लिए कॉल की जगह है समस्या है लेकिन एक चाल मैं अक्सर इन समस्याओं को दूर करने में इस्तेमाल किया है समाधान नहीं करता है: यह अन्य प्रश्न के मेरा उत्तर चेकआउट बिल्टिन 'मानचित्र'। –