c - समझना POSIX-कांटा()




operating-system fork (2)

आपका दूसरा दृष्टिकोण सही नहीं है। क्योंकि fork() बाद fork() बच्चे की प्रक्रिया i के वर्तमान मूल्य को संभालती है i यह हर किसी के लिए निर्धारित नहीं है, जो हर समय fork() कहलाता है और न ही उन्हें कचरा मूल्य मिलता है। इसलिए, आपके कोड में कांटा बम नहीं हो सकता तथ्य यह है कि यह एक स्थानीय चर अप्रासंगिक है। fork() क्लोनों को बहुत ज्यादा सबकुछ और बच्चे की प्रक्रिया अपने माता-पिता के समान है, कुछ चीजों को छोड़कर जैसे कि POSIX मैनुअल में बताया गया है।

मैं समझाए जाने में आसानी के लिए लूप गिनती 2 को कम कर दूँगा और सभी fork() कॉल्स को सफल करूँगा:

   for (i = 0; i < 2; i++) {
        fork();
    }
    printf("%s\n", "here");

1) जब i=0 , fork() निष्पादित किया जाता है और अब दो प्रक्रियाएं हैं उन्हें पी 1 और पी 2 कॉल करें

2) अब, प्रत्येक P1 और P2 प्रक्रियाएं i = 0 में लूप और वेतन वृद्धि i से 1 के साथ जारी रहती हैं। लूप की स्थिति के लिए सच है, इसलिए उनमें से प्रत्येक एक और दो प्रक्रियाओं को उत्पन्न करता है और कुल में 4. उन्हें पी 1 ए और पी 1 बी और पी 2 ए और कॉल करें। P2b। सभी 4 प्रक्रियाओं में अब I = 1 है और इसे 2 तक बढ़ाना (जैसा कि वे लूप जारी रखते हैं)।

3) अब, सभी 4 प्रक्रियाओं में i रूप में 2 का मान है और लूप की स्थिति उन सभी में गलत है और "यहां" 4 बार (हर प्रक्रिया से एक) मुद्रित किया जाएगा।

यदि यह मदद करता है, तो आप लूप को while लूप में कनवर्ट कर सकते हैं और i प्रत्येक fork() से लौटने वाले दोनों प्रक्रियाओं से बढ़ता कैसे हो सकता है थोड़ा और अधिक स्पष्ट हो सकता है:

    i = 0;
   while(i < 2) {
        fork();
        i++;
    }
    printf("%s\n", "here");

मैं fork समारोह के बारे में पढ़ रहा था और यह नई प्रक्रियाएं कैसे बनाता है निम्नलिखित प्रोग्राम ठीक चलाता है और here सोलह बार प्रिंट करता here , लेकिन, मुझे निष्पादन के प्रवाह को समझने में समस्या हो रही है:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h> 

int main() 
{ 
    int i; 
    for (i = 0; i < 4; i++) { // line no. 12
        fork();               // line no. 13
    }
    printf("%s\n", "here");
    return 0; 
}

मुझे लगता है कि इस कार्यक्रम को दो तरीकों से देखा जा सकता है:

पहला दृष्टिकोण: fork() को कुल चार बार कहा जाता है अगर मैं लूप को चार कॉलों के साथ fork() फ़ंक्शन में fork() हूं, तो चीजें जगह में गिरती हैं और मैं समझता हूं कि here 2 ^ 4 बार प्रिंट क्यों किया here है।

द्वितीय दृष्टिकोण: fork() एक नई प्रक्रिया को पैदा करता है, जहां से इसे लागू किया जाता है और इनमें से प्रत्येक बाल प्रक्रियाओं का अपना स्थानीय चर है। तो, लाइन नंबर के बाद 13, इनमें से प्रत्येक बच्चे की प्रक्रियाएं पाश ( } ) के अंत को देखते हैं और वे लाइन नंबर पर जाते हैं। 12. चूंकि, इन सभी बाल प्रक्रियाओं का अपना स्थानीय वैरिएबल i को 0 पर सेट किया गया है (शायद i कुछ कचरा मूल्य पर सेट है?), वे सभी फिर से कांटा। फिर से इन बच्चों के लिए अपने लोकल वेरिएबल i को 0 पर सेट कर दिया जाता है। इसके परिणामस्वरूप फोर्क बम का परिणाम होगा।

मैं निश्चित रूप से मेरे 2 दृष्टिकोण में कुछ याद कर रहा हूं, क्या कोई कृपया मदद करता है?

धन्यवाद।


आपका पहला दृष्टिकोण सही था।
यह एक बढ़िया जवाब है, इसलिए मैं आपको सभी तकनीकी विवरण दे दूँगा।

जब fork कहा जाता है, तो कई चीजें होती हैं:

  • एक नई प्रक्रिया बनाई जाती है ('बच्चे')
  • माता-पिता की ढेर दोहराया जाता है, और बच्चे को सौंपा जाता है।
  • बच्चे के स्टैक पॉइंटर को माता-पिता के लिए सेट किया गया है
  • बच्चे की पीआईडी ​​(प्रक्रिया आईडी) माता-पिता को वापस कर दी जाती है।
  • शून्य बच्चे को वापस कर दिया जाता है

किसी फ़ंक्शन के अंदर घोषित चर को स्टैक में संग्रहित किया जाता है, और इसलिए समान मूल्य से शुरू होता है, लेकिन साझा नहीं किया जाता है।
फ़ंक्शन (शीर्ष स्तर पर) के बाहर घोषित चर चर में नहीं हैं, इसलिए बच्चे / माता-पिता के बीच साझा किया जाता है

(कुछ अन्य चीजें डुप्लिकेट नहीं हैं या नहीं, अधिक जानकारी के लिए man fork देखें।)

इसलिए, जब आप अपना कोड चलाते हैं:

    what happens                    # of processes  
1. the parent forks.                2  
2. the parent and it's child fork.  4  
3. everyone forks                   8  
4. everyone forks                   16  
5. everyone prints "here".          16

आप सोलह प्रक्रियाओं के साथ समाप्त होते हैं, और शब्द 'यहाँ' सोलह बार।

मूल रूप से,

if(fork() != 0) {
    parent_stuff();
} else {
    child_stuff();
}




posix