2013-08-11 15 views
8

मैं पाइथन मल्टीप्रोसेसिंग सीखने की कोशिश कर रहा हूं।पायथन मल्टीप्रोसेसिंग दस्तावेज़ीकरण उदाहरण

from multiprocessing import Process 
import os 

def info(title): 
    print title 
    print 'module name:', __name__ 
    if hasattr(os, 'getppid'): # only available on Unix 
     print 'parent process:', os.getppid() 
    print 'process id:', os.getpid() 

def f(name): 
    info('function f') 
    print 'hello', name 

if __name__ == '__main__': 
    info('main line') 
    p = Process(target=f, args=('bob',)) 
    p.start() 
    p.join() 

वास्तव में क्या मैं तलाश में हूं:

के उदाहरण से http://docs.python.org/2/library/multiprocessing.html "व्यक्तिगत प्रक्रिया शामिल आईडी दिखाने के लिए, यहाँ एक विस्तारित उदाहरण है"? मैं देखता हूं कि def f (name): जानकारी ('मुख्य पंक्ति') समाप्त होने के बाद बुलाया जाता है, लेकिन यह सिंक्रोनस कॉल वैसे भी डिफ़ॉल्ट होगा। मैं देखता हूं कि एक ही प्रक्रिया की जानकारी ('मुख्य पंक्ति') def f (name) का मूल पीआईडी ​​है: लेकिन यह सुनिश्चित नहीं है कि इसके बारे में 'मल्टीप्रोसेसिंग' क्या है।

इसके अलावा, शामिल होने के साथ() "कॉलिंग थ्रेड को उस प्रक्रिया तक अवरुद्ध करें जब उसकी जॉइन() विधि को टर्मिनेट कहा जाता है"। मैं स्पष्ट नहीं हूं कि कॉलिंग थ्रेड क्या होगा। इस उदाहरण में क्या अवरोध() अवरुद्ध होगा?

उत्तर

25

कैसे multiprocessing काम करता है, संक्षेप में:

  • Process() spawns (fork या यूनिक्स सिस्टम पर समान) मूल कार्यक्रम की एक प्रतिलिपि (विंडोज, जो एक असली fork का अभाव है पर, यह मुश्किल है और मॉड्यूल दस्तावेज नोट्स विशेष देखभाल की आवश्यकता है)।
  • प्रतिलिपि मूल के साथ संवाद करती है यह पता लगाने के लिए कि (ए) यह एक प्रति है और (बी) इसे बंद करना चाहिए और target= फ़ंक्शन (नीचे देखें) का आह्वान करना चाहिए।
  • इस बिंदु पर, मूल और प्रतिलिपि अब अलग और स्वतंत्र हैं, और एक साथ चल सकते हैं।

चूंकि इन स्वतंत्र प्रक्रियाएं हैं, वे अब स्वतंत्र वैश्विक दुभाषिया ताले (CPython में) है, इसलिए दोनों जब तक वे के लिए संघर्ष नहीं है के रूप में एक बहु CPU बॉक्स पर एक सीपीयू की 100% तक उपयोग कर सकते हैं, अन्य निचले स्तर (ओएस) संसाधन। वह "मल्टीप्रोसेसिंग" हिस्सा है।

बेशक, किसी बिंदु पर आपको इन अनुमानित-स्वतंत्र प्रक्रियाओं के बीच डेटा भेजना होगा, उदाहरण के लिए, एक (या कई) कार्यकर्ता प्रक्रिया (एसएस) से परिणामों को "मुख्य" प्रक्रिया में वापस भेजने के लिए। (कभी-कभार अपवाद होता है जहां हर कोई पूरी तरह से स्वतंत्र होता है, लेकिन यह दुर्लभ है ... साथ ही पूरे स्टार्ट-अप अनुक्रम भी हैं, p.start() द्वारा लात मारी गई।) इसलिए प्रत्येक ने Process इंस्टेंस- p बनाया, उपर्युक्त उदाहरण में - एक संचार चैनल है अपने मूल निर्माता और इसके विपरीत (यह एक सममित कनेक्शन है)। multiprocessing मॉड्यूल pickle मॉड्यूल का उपयोग स्ट्रिंग्स में डेटा को चालू करने के लिए करता है- उसी स्ट्रिंग्स जिन्हें आप pickle.dump के साथ फाइलों में छीन सकते हैं- और चैनलों में डेटा भेजता है, श्रमिकों को "नीचे" श्रमिकों को तर्क और ऐसे, और "ऊपर" श्रमिकों को भेजता है परिणाम वापस भेजें।

आखिरकार, परिणाम मिलने के बाद आप सब कुछ कर लेंगे, कार्यकर्ता समाप्त होता है (target= फ़ंक्शन से लौटकर) और माता-पिता को यह बताता है कि यह किया गया है। यह सुनिश्चित करने के लिए कि सबकुछ बंद हो गया है और साफ हो गया है, माता-पिता को कार्यकर्ता के "मैं कर चुका हूं" संदेश (वास्तव में एक ओएस-स्तर exit यूनिक्स-आइश sysems पर) के लिए प्रतीक्षा करने के लिए p.join() पर कॉल करना चाहिए।

उदाहरण थोड़ा सा मूर्ख है क्योंकि दो मुद्रित संदेश मूल रूप से कोई समय नहीं लेते हैं, इसलिए उन्हें "एक ही समय में" चलाने से कोई मापनीय लाभ नहीं होता है। लेकिन मान लें कि hello प्रिंट करने की बजाय, f π (3.1415 9 ...) के पहले 100,000 अंकों की गणना करना था। फिर आप Process, p2 को एक अलग लक्ष्य g के साथ आगे बढ़ा सकते हैं जो ई (2.71828 ...) के पहले 100,000 अंकों की गणना करता है। ये स्वतंत्र रूप से भाग लेंगे।माता-पिता दोनों को पूरा करने के लिए p.join() और p2.join() पर कॉल करने के लिए कॉल कर सकते हैं (या फिर अधिक काम करने के लिए और अधिक श्रमिकों को और अधिक CPU पर कब्जा कर सकते हैं, या यहां तक ​​कि कुछ समय के लिए अपना काम भी कर सकते हैं)।

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