2017-07-25 26 views
5

मेरे पास कुछ जटिल वर्ग है जो कक्षा बी से इनपुट डेटा का उपभोग करते समय डेटा (बड़ी मैट्रिक्स गणना) की गणना करता है।पायथन 3 मल्टीप्रोसेसिंग। कक्षा के अंदर प्रोसेस?

स्वयं एकाधिक कोर का उपयोग करता है। हालांकि, जब डेटा के अगले हिस्से की आवश्यकता है, तो यह उसी समय के थ्रेड में बी रनों के बाद से कुछ समय तक प्रतीक्षा करता है।

के बाद से एक मुख्य रूप से संगणना के लिए GPU का उपयोग करता है, मैं बी CPU पर समवर्ती डेटा इकट्ठा करने के लिए करना चाहते हैं।

मेरे नवीनतम दृष्टिकोण था:

class B(object): 

    def __init__(self, ...): 
     ... 
     self._queue = multiprocessing.Queue(10) 
     loader = multiprocessing.Process(target=self._concurrent_loader) 

    def _concurrent_loader(self): 
     while True: 
      if not self._queue.full(): 
       # here: data loading from disk and pre-processing 
       # that requires access to instance variables 
       # like self.path, self.batch_size, ... 
       self._queue.put(data_chunk) 
      else: 
       # don't eat CPU time if A is too busy to consume 
       # the queue at the moment 
       time.sleep(1) 

    def get_data(self): 
     return self._queue.get() 

इस दृष्टिकोण एक "pythonic" समाधान पर विचार किया जा सकता है:

# every time *A* needs data 
def some_computation_method(self): 
    data = B.get_data() 
    # start computations with data 

... और बी लगभग इस तरह दिखता है?

चूंकि मुझे पाइथन के मल्टीप्रोसेसिंग मॉड्यूल के साथ अधिक अनुभव नहीं है, इसलिए मैंने एक आसान/सरल दृष्टिकोण बनाया है। हालांकि, यह मुझे "हैकी" की तरह दिखता है।

क्या समवर्ती और कुछ कतार के माध्यम से यह आपूर्ति डिस्क से एक वर्ग बी डेटा लोड करने के लिए एक बेहतर समाधान है, जबकि मुख्य थ्रेड भारी संगणना चलाता है और समय-समय पर कतार से डेटा की खपत हो सकता है?

उत्तर

1

जबकि आपका समाधान पूरी तरह से ठीक है, खासकर "छोटी" परियोजनाओं के लिए, यह B वर्ग के साथ कसकर मिलकर थ्रेडिंग का नकारात्मक हिस्सा है। इसलिए यदि आप (उदाहरण के लिए) किसी कारण से Bगैर -threaded तरीके से, अपने भाग्य से बाहर करना चाहते थे।

मैं व्यक्तिगत रूप से एक धागा सुरक्षित तरीके से वर्ग लिखते थे, और फिर इसे बाहर से धागे का उपयोग कर फोन:

class B(object): 
    def __init__(self): 
     self._queue = multiprocessing.Queue(10) 

    ... 

if __name__ == '__main__': 
    b = B() 

    loader = multiprocessing.Process(target=b._concurrent_loader) 
    loader.start() 

यह B अधिक लचीला, निर्भरता बेहतर अलग करती है और परीक्षण करने के लिए आसान है बनाता है। यह थ्रेड सृजन के बारे में स्पष्ट होने के कारण कोड को और अधिक पठनीय बनाता है, इसकी तुलना में वर्ग निर्माण पर पूरी तरह से हो रहा है।

संबंधित मुद्दे