c - एक लूप लूप में कांटा() के साथ क्या होता है




fork (2)

  1. हाँ यह सही है। (निचे देखो)
  2. नहीं, i++ fork के कॉल के बाद निष्पादित किया जाता है, क्योंकि लूप काम करता है।
  3. अगर सब सफलतापूर्वक चला जाता है, हाँ। हालांकि, याद रखें कि fork असफल हो सकता है।

दूसरे पर एक छोटी सी व्याख्या:

for (i = 0;i < 3; i++)
{
   fork();
}

के समान है:

i = 0;
while (i < 3)
{
    fork();
    i++;
}

तो i फोर्क प्रक्रियाओं (माता-पिता और बच्चे दोनों) में वृद्धि से पहले मूल्य है। हालांकि, fork() तुरंत बाद वृद्धि को निष्पादित किया जाता है, इसलिए मेरी राय में, आरेख को सही के रूप में माना जा सकता है।

मैं fork() व्यवहार को समझने की कोशिश कर रहा हूं। इस बार for-loop । निम्नलिखित कोड का निरीक्षण करें:

#include <stdio.h>

void main()
{
   int i;

   for (i=0;i<3;i++)
   {
      fork();

      // This printf statement is for debugging purposes
      // getppid(): gets the parent process-id
      // getpid(): get child process-id

      printf("[%d] [%d] i=%d\n", getppid(), getpid(), i);
   }

   printf("[%d] [%d] hi\n", getppid(), getpid());
}

आउटपुट यहां है:

[6909][6936] i=0
[6909][6936] i=1
[6936][6938] i=1
[6909][6936] i=2
[6909][6936] hi
[6936][6938] i=2
[6936][6938] hi
[6938][6940] i=2
[6938][6940] hi
[1][6937] i=0
[1][6939] i=2
[1][6939] hi
[1][6937] i=1
[6937][6941] i=1
[1][6937] i=2
[1][6937] hi
[6937][6941] i=2
[6937][6941] hi
[6937][6942] i=2
[6937][6942] hi
[1][6943] i=2
[1][6943] hi

मैं एक बहुत ही दृश्यमान व्यक्ति हूं, और इसलिए चीजों को वास्तव में समझने का एकमात्र तरीका आरेखण द्वारा है। मेरे प्रशिक्षक ने कहा कि 8 हाय स्टेटमेंट होंगे। मैंने कोड लिखा और भाग लिया, और वास्तव में 8 हाय स्टेटमेंट थे। लेकिन मैं वास्तव में इसे समझ में नहीं आया। तो मैंने निम्नलिखित चित्र खींचा:

टिप्पणियों को प्रतिबिंबित करने के लिए अद्यतन चित्र :)

टिप्पणियों:

  1. अभिभावक प्रक्रिया (मुख्य) लूप को 3 बार फिर से चालू करना चाहिए। फिर printf कहा जाता है
  2. पैरेंट फॉर-लूप के प्रत्येक पुनरावृत्ति पर एक कांटा () कहा जाता है
  3. प्रत्येक कांटा () कॉल के बाद, मुझे वृद्धि हुई है, और इसलिए हर बच्चा बढ़ने से पहले मेरे लिए एक लूप शुरू करता है
  4. प्रत्येक फॉर-लूप के अंत में, "हाय" मुद्रित होता है

यहां मेरे प्रश्न हैं:

  • क्या मेरा आरेख सही है?
  • आउटपुट में i=0 दो उदाहरण क्यों हैं?
  • कांटा () के बाद प्रत्येक बच्चे को i क्या महत्व दिया जाता है? यदि मेरा वही मूल्य ले लिया जाता है, तो "फोर्किंग" कब बंद होता है?
  • क्या यह हमेशा ऐसा मामला है कि 2^n - 1 फोर्क किए गए बच्चों की संख्या को गिनने का एक तरीका होगा? तो, यहां n=3 , जिसका अर्थ है 2^3 - 1 = 8 - 1 = 7 बच्चे, जो सही है?

अपने प्रश्नों का उत्तर एक-एक करके:

क्या मेरा आरेख सही है?

हाँ, अनिवार्य रूप से। यह भी एक बहुत अच्छा आरेख है।

यह कहना है, अगर आप पूर्ण लूप पुनरावृत्तियों का जिक्र करते हुए i=0 आदि लेबल की व्याख्या करते हैं तो यह सही है। हालांकि, चित्र क्या नहीं दिखाता है, यह है कि, प्रत्येक fork() बाद, fork() कॉल के बाद वर्तमान लूप पुनरावृत्ति का हिस्सा फोर्कड बाल प्रक्रिया द्वारा भी निष्पादित किया जाता है।

आउटपुट में i=0 दो उदाहरण क्यों हैं?

क्योंकि आपके पास fork() printf() बाद printf() , इसलिए इसे मूल प्रक्रिया और केवल फोर्कड बाल प्रक्रिया दोनों द्वारा निष्पादित किया जाता है। यदि आप printf() को fork() printf() से पहले ले जाते हैं, तो इसे केवल माता-पिता द्वारा निष्पादित किया जाएगा (चूंकि बाल प्रक्रिया अभी तक मौजूद नहीं है)।

fork() बाद प्रत्येक बच्चे को i क्या महत्व दिया जाता है? यदि मेरा वही मूल्य ले लिया जाता है, तो "फोर्किंग" कब बंद होता है?

i मूल्य fork() द्वारा नहीं बदला जाता है, इसलिए बाल प्रक्रिया अपने माता-पिता के समान मूल्य को देखती है।

fork() बारे में याद रखने की बात यह है कि इसे एक बार बुलाया जाता है, लेकिन यह दो बार लौटाता है - एक बार मूल प्रक्रिया में, और एक बार नव क्लोन बाल प्रक्रिया में।

एक सरल उदाहरण के लिए, निम्न कोड पर विचार करें:

printf("This will be printed once.\n");
fork();
printf("This will be printed twice.\n");
fork();
printf("This will be printed four times.\n");
fork();
printf("This will be printed eight times.\n");

fork() द्वारा बनाई गई बाल प्रक्रिया अपने माता-पिता का एक (लगभग) सटीक क्लोन है, और इसलिए, अपने दृष्टिकोण से, यह अपने माता-पिता होने के नाते "याद करता है", सभी मूल प्रक्रिया की स्थिति को विरासत में लेता है (सभी परिवर्तनीय मूल्यों सहित, कॉल ढेर और निर्देश निष्पादित किया जा रहा है)। एकमात्र तत्काल अंतर (सिस्टम मेटाडेटा के अलावा, जैसे getpid() द्वारा लौटाई गई प्रक्रिया आईडी, fork() का रिटर्न वैल्यू है, जो कि बच्चे की प्रक्रिया में शून्य होगी लेकिन गैर-शून्य (वास्तव में, बाल प्रक्रिया की आईडी ) माता-पिता में।

क्या यह हमेशा ऐसा मामला है कि 2^n - 1 फोर्क किए गए बच्चों की संख्या को गिनने का एक तरीका होगा? तो, यहां n=3 , जिसका अर्थ है 2^3 - 1 = 8 - 1 = 7 बच्चे, जो सही है?

प्रत्येक प्रक्रिया जो एक fork() निष्पादित करती है, दो प्रक्रियाओं में बदल जाती है (असामान्य त्रुटि स्थितियों के तहत, जहां fork() विफल हो सकता है)। यदि माता-पिता और बच्चे एक ही कोड को निष्पादित करते रहते हैं (यानी वे fork() , या अपनी स्वयं की प्रक्रिया आईडी, और शाखा के आधार पर अलग-अलग कोड पथों के वापसी मूल्य की जांच नहीं करते हैं), तो प्रत्येक बाद का कांटा संख्या को दोगुना कर देगा प्रक्रियाओं का। तो, हाँ, तीन कांटे के बाद, आप कुल में 2³ = 8 प्रक्रियाओं के साथ समाप्त हो जाएगा।





fork