2015-11-06 5 views
5

मैं अजगर में बहु प्रसंस्करण सीख रहा हूं। मैंने मल्टीप्रोसेसिंग की कोशिश की और मल्टीप्रोसेसिंग मॉड्यूल के स्रोत कोड को पढ़ने के बाद, मैंने पाया कि यह os.fork() का उपयोग करता है, इसलिए मैं os.fok() का परीक्षण करने के लिए कुछ कोड लिखता हूं, लेकिन मैं अटक गया हूं।पायथन: कैसे os.fork() काम करता है?

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import os 
import time 

for i in range(2): 
    print '**********%d***********' % i 
    pid = os.fork() 
    print "Pid %d" % pid 

मुझे लगता है कि प्रत्येक प्रिंट दो बार निष्पादित किया जाएगा, लेकिन वे तीन निष्पादित times.I यह कैसे काम समझ में नहीं कर सकते हैं: मेरे कोड निम्नलिखित के रूप में है? मैं इस Need to know how fork works?
क्या इस लेख कहना है कि वह भी दो बार निष्पादित किया जाएगा से पढ़ते हैं, तो मैं तो stucked हूँ ......

उत्तर

9

अंतर्निहित ओएस समारोह fork() फोन करके प्रश्न सीधे os.fork() काम करता है जवाब देने के लिए,।

लेकिन आप निश्चित रूप से यह है कि क्या करता है में रुचि रखते हैं। वैसे यह एक और प्रक्रिया बनाता है जो इस तरह एक ही स्थान पर फिर से शुरू होगा। तो सबसे पहले पाश रन के भीतर, आप जिसके बाद आप दो प्रक्रियाओं, "मूल एक" (जो बच्चे की प्रक्रिया के पीआईडी ​​का एक pid मूल्य हो जाता है) एक कांटा और काँटेदार एक (जो 0 के pid मूल्य हो जाता है) मिल ।

वे दोनों उनके pid मूल्य प्रिंट और 2 पाश रन है, जो वे दोनों प्रिंट के साथ चले जाते हैं। फिर वे दोनों कांटा, आपको 4 प्रक्रियाओं के साथ छोड़ देते हैं जो सभी अपने संबंधित pid मूल्यों को प्रिंट करते हैं। उनमें से दो 0 होना चाहिए, अन्य दो को अभी बनाए गए बच्चे के पीआईडी ​​होना चाहिए।

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import os 
import time 

for i in range(2): 
    print '**********%d***********' % i 
    pid = os.fork() 
    if pid == 0: 
     print "%d just was created." % os.getpid() 
    else: 
     print "%d just created %d." % (os.getpid(), pid) 

करने के लिए कोड बदलने से आप क्या होता है बेहतर देखेंगे: प्रत्येक प्रक्रिया आप अपने स्वयं के पीआईडी ​​और क्या कांटा पर हुआ बता देंगे।

+0

आप सही हैं। और मुझे गहरे कांटे से बचने के लिए opr.exit() को उपप्रोसेसर में कॉल करना चाहिए ... – tudouya

+0

@tudouya दाएं। या बस लूप से बाहर तोड़ो। – glglgl

10

सबसे पहले, कि print '******...' पंक्ति निकाल दें। यह सिर्फ हर किसी को भ्रमित करता है। इसके बजाय, आइए इस कोड को आजमाएं ...

import os 
import time 

for i in range(2): 
    print "I'm about to be a dad!" 
    time.sleep(5) 
    pid = os.fork() 
    if pid == 0: 
     print "I'm {}, a newborn that knows to write to the terminal!".format(os.getpid()) 
    else: 
     print "I'm the dad of {}, and he knows to use the terminal!".format(pid) 
     os.waitpid(pid) 

ठीक है, सबसे पहले, "कांटा" क्या है? कांटा आधुनिक और मानक अनुरूप ऑपरेटिंग सिस्टम की एक विशेषता है (एम $ विंडोज के अलावा: एक OS के उस मजाक लेकिन सभी आधुनिक और मानक संगत) है कि एक प्रक्रिया (उर्फ अनुमति देता है: "कार्यक्रम", और कहा कि शामिल पाइथन दुभाषिया!) सचमुच एक सटीक डुप्लिकेट बनाने के लिए, प्रभावी रूप से एक नई प्रक्रिया ("कार्यक्रम" का एक और उदाहरण) बनाते हैं। एक बार जादू हो जाने के बाद, दोनों प्रक्रियाएं स्वतंत्र होती हैं। उनमें से किसी एक में बदलना दूसरे को प्रभावित नहीं करता है।

प्रक्रिया इस अंधेरे और प्राचीन जादू वर्तनी माता पिता की प्रक्रिया के रूप में जाना जाता है के लिए जिम्मेदार। जीवन के प्रति इस अनैतिक घृणा का सौहार्दपूर्ण परिणाम बाल प्रक्रिया के रूप में जाना जाता है।

सभी के लिए यह स्पष्ट होगा, जिसमें वे नहीं हैं, आप प्रोग्रामर के उस चुनिंदा समूह के सदस्य बन सकते हैं जिन्होंने os.fork() के माध्यम से अपनी आत्मा बेची है। यह फ़ंक्शन एक कांटा ऑपरेशन करता है, और इस प्रकार पतली हवा से दूसरी प्रक्रिया बनाई जाती है।

अब, यह फ़ंक्शन क्या लौटाता है, या अधिक महत्वपूर्ण बात, कैसे यह भी वापस आती है? यदि आप पागल नहीं बनना चाहते हैं, कृपया लिनक्स कर्नेल की /kernel/fork.c फ़ाइल को न जाएं और पढ़ें!एक बार कर्नेल जो करता है उसे हम जानते हैं, लेकिन हम इसे स्वीकार नहीं करना चाहते हैं, os.fork()में दो प्रक्रियाओं में वापसी करता है! हां, यहां तक ​​कि कॉल स्टैक की प्रतिलिपि बनाई गई है!

तो, यदि उनकी सटीक प्रतियां हैं, तो माता-पिता और बच्चे के बीच एक अंतर कैसे होता है? सरल। यदि os.fork() का परिणाम शून्य है, तो आप बच्चे में काम कर रहे हैं। अन्यथा, आप माता-पिता में काम कर रहे हैं, और वापसी मूल्य बच्चे के पीआईडी ​​(प्रक्रिया पहचानकर्ता) है। वैसे भी, बच्चे को os.getpid() से अपना स्वयं का पीआईडी ​​मिल सकता है, नहीं?

अब, इसे ध्यान में रखते हुए, और तथ्य यह है कि एक लूप के अंदर fork() करना गड़बड़ी के लिए नुस्खा है, यही होता है। के मूल प्रक्रिया "मास्टर" प्रक्रिया कहते हैं ...

  • मास्टर: i = 0, बच्चे के # 1-ऑफ-द मास्टर में कांटे
    • बच्चे के # 1-ऑफ-द मास्टर: i = 1 कांटे में बच्चे के # 1 के- बच्चे के # 1-ऑफ-द मास्टर
    • बच्चे के # 1 के- बच्चे के # 1-ऑफ-द मास्टर: से अधिक for पाश, बाहर निकालता है
    • बच्चे के # 1-ऑफ-द मास्टर : for लूप ओवर,
  • से बाहर निकलता है 63,210
  • मास्टर: i = 1, बच्चे के # 2-ऑफ-द मास्टर में कांटे बच्चे के के- मास्टर 2
    • #: i = 1 कांटे में बच्चे के # 1 के- बच्चे के # 2-ऑफ-द मास्टर
    • बच्चे के # 1 के- बच्चे के # 2-ऑफ-द मास्टर: से अधिक for पाश, बाहर निकालता है
    • बच्चे के # 2-ऑफ-द मास्टर: से अधिक for पाश,
  • मास्टर बाहर निकालता है: for पाश से अधिक ,
से बाहर निकलता है

जैसा कि आप देख सकते हैं, वहाँ 6 प्रक्रियाओं की कुल तरह उत्पादन का 6 लाइनों में जिसके परिणामस्वरूप, कुछ कर रहे हैं ...

मैं 12120 के पिता हूँ, और वह टर्मिनल का उपयोग करने जानता है!

मैं 12120 हूं, एक नवजात शिशु जो टर्मिनल को लिखना जानता है!

मैं 12121 का पिता हूं, और वह टर्मिनल का उपयोग करना जानता है!

मैं 12121 हूं, एक नवजात शिशु जो टर्मिनल को लिखना जानता है!

मैं 12122 का पिता हूं, और वह टर्मिनल का उपयोग करना जानता है!

मैं 12122 हूं, एक नवजात शिशु जो टर्मिनल को लिखना जानता है!

लेकिन वह सिर्फ मनमाना है, यह उत्पादन इस बाहर के बजाय हो सकता था ...

मैं 12120 हूँ, एक नवजात टर्मिनल के लिए लिखने के लिए जानता है कि!

मैं 12120 का पिता हूं, और वह टर्मिनल का उपयोग करना जानता है!

मैं 12121 हूं, एक नवजात शिशु जो टर्मिनल को लिखना जानता है!

मैं 12121 का पिता हूं, और वह टर्मिनल का उपयोग करना जानता है!

मैं 12122 हूं, एक नवजात शिशु जो टर्मिनल को लिखना जानता है!

मैं 12122 का पिता हूं, और वह टर्मिनल का उपयोग करना जानता है!

या इसके अलावा कुछ भी। ओएस (और आपकी मदरबोर्ड की फंकी घड़ियों) ऑर्डर के लिए एकमात्र ज़िम्मेदार है जिसमें प्रक्रियाओं को समय-समय पर मिलता है, इसलिए blame on Torvalds (and expect no self-steem when back) पर जाएं यदि आप नापसंद करते हैं कि कर्नेल आपकी प्रक्रियाओं को व्यवस्थित करने का प्रबंधन कैसे करता है;)।

मुझे आशा है कि इससे आपको कुछ प्रकाश मिलेगा!

+2

बहुत अच्छी व्याख्या। –

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