c - यह कार्यक्रम "फोर्कड" क्यों प्रिंट करता है 4 बार?




linux unix (4)

एक main() और अन्य तीन से fork()

ध्यान दें कि सभी तीन forks() को निष्पादित किया जा रहा है। आप ref पर एक नज़र डालना चाहते हैं:

प्रतिलाभ की मात्रा

सफल समापन पर, कांटा () बच्चे की प्रक्रिया में 0 लौटाएगा और बाल प्रक्रिया की प्रक्रिया आईडी को मूल प्रक्रिया में वापस कर देगा । दोनों प्रक्रियाओं कांटा () फ़ंक्शन से निष्पादित करना जारी रहेगा। अन्यथा, -1 को मूल प्रक्रिया में वापस कर दिया जाएगा, कोई भी बाल प्रक्रिया नहीं बनाई जाएगी, और त्रुटि को इंगित करने के लिए त्रुटि सेट की जाएगी।

ध्यान दें कि प्रक्रिया आईडी शून्य नहीं हो सकती है, जैसा कि here बताया गया here

तो वास्तव में क्या होता है?

हमारे पास है:

fork() && (fork() || fork());

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

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

अब, मूल प्रक्रिया में दूसरा fork() निष्पादित किया जा रहा है, यह करता है और यह मूल प्रक्रिया में गैर-शून्य मान देता है और बच्चे की प्रक्रिया में शून्य होता है।

तो अब, माता-पिता अंतिम fork() (शॉर्ट सर्किटिंग के कारण fork() निष्पादन जारी नहीं रखेंगे, जबकि बाल प्रक्रिया आखिरी कांटा निष्पादित करेगी, क्योंकि पहले ऑपरेंड || 0 है

तो इसका मतलब है कि हमें दो और प्रिंट मिलेगा।

नतीजतन, हम कुल मिलाकर चार प्रिंट प्राप्त करते हैं।

लघु सर्किटिंग

यहां, लघु सर्किटिंग का मूल रूप से अर्थ है कि यदि & & amp का पहला ऑपरेंड शून्य है, तो अन्य ऑपरेंड का मूल्यांकन / मूल्यांकन नहीं किया जाता है। एक ही तर्क पर, अगर एक का संचालन || 1 है, तो शेष ऑपरेटरों को मूल्यांकन की आवश्यकता नहीं है। ऐसा इसलिए होता है क्योंकि शेष ऑपरेशंस तर्क अभिव्यक्ति के परिणाम को नहीं बदल सकते हैं, इसलिए उन्हें निष्पादित करने की आवश्यकता नहीं है, इस प्रकार हम समय बचाते हैं।

नीचे उदाहरण देखें।

प्रक्रिया

याद रखें कि एक मूल प्रक्रिया संतान प्रक्रियाएं बनाती है जो बदले में अन्य प्रक्रियाएं बनाती हैं और इसी तरह। इससे प्रक्रियाओं का पदानुक्रम होता है (या एक पेड़ जो कह सकता है)।

इसे ध्यान में रखते हुए, इस समान समस्या को देखने के लायक है , साथ ही this उत्तर भी।

वर्णनात्मक छवि

मैंने यह आंकड़ा भी बनाया जो मुझे लगता है, मदद कर सकता है। मैंने माना कि प्रत्येक कॉल के लिए पिड का fork() वापस 3, 4 और 5 है।

ध्यान दें कि कुछ fork() ऊपर एक लाल एक्स है, जिसका अर्थ है कि वे तर्क अभिव्यक्ति के लघु-सर्किट मूल्यांकन के कारण निष्पादित नहीं किए जाते हैं।

शीर्ष पर fork() एस निष्पादित नहीं किया जा रहा है, क्योंकि ऑपरेटर का पहला ऑपरेंड 0 && 0 है, इस प्रकार पूरी अभिव्यक्ति का परिणाम 0 होगा, इसलिए एंड्रॉइड के बाकी ऑपरेंड को निष्पादित करने में कोई सार नहीं है &&

तल पर fork() को निष्पादित नहीं किया जाएगा, क्योंकि यह एक दूसरा ऑपरेंड है || , जहां इसका पहला ऑपरेंड एक गैर-शून्य संख्या है, इस प्रकार अभिव्यक्ति का नतीजा पहले से ही सत्य पर मूल्यांकन किया जाता है, इससे कोई फर्क नहीं पड़ता कि दूसरा ऑपरेंड क्या है।

और अगली तस्वीर में आप प्रक्रियाओं के पदानुक्रम देख सकते हैं: पिछले आंकड़े के आधार पर।

लघु सर्किटिंग का उदाहरण

#include <stdio.h>

int main(void) {

  if(printf("A printf() results in logic true\n"))
    ;//empty body

  if(0 && printf("Short circuiting will not let me execute\n"))
    ;
  else if(0 || printf("I have to be executed\n"))
    ;
  else if(1 || printf("No need for me to get executed\n"))
    ;
  else
  printf("The answer wasn't nonsense after all!\n");

  return 0;
}

आउटपुट:

A printf() results in logic true
I have to be executed

यह कार्यक्रम "फोर्कड" क्यों प्रिंट करता है 4 बार?

#include <stdio.h>
#include <unistd.h>

int main(void) {

  fork() && (fork() || fork());

  printf("forked!\n");
  return 0;
}

निष्पादन fork() && (fork() || fork()) , क्या होता है

प्रत्येक fork क्रमशः मूल्यों के साथ 2 प्रक्रियाओं को देता है (पैरेंट) और 0 (बच्चे)

पहला कांटा:

  • अभिभावक वापसी मान pid null => निष्पादित करता है && (fork() || fork())
    • दूसरा कांटा पैरेंट वैल्यू पिड नहीं है जो निष्पादित करता है भाग => मुद्रित मुद्रित
    • दूसरा कांटा बच्चा मूल्य = 0 => निष्पादित करता है || fork() || fork()
      • तीसरा कांटा अभिभावक प्रिंट forked
      • तीसरा कांटा बच्चा प्रिंट forked
  • बाल वापसी मान 0 = & part => मुद्रित forked किए गए निष्पादन को रोकता है

कुल: 4 forked


मुझे उन सभी उत्तरों को पसंद है जो पहले ही सबमिट कर चुके हैं। शायद अगर आपने अपने printf कथन में कुछ और चर जोड़े हैं, तो यह देखने के लिए आपके लिए क्या आसान होगा।

#include<stdio.h>
#include<unistd.h>

int main(){

   long child = fork() && (fork() || fork());
   printf("forked! PID=%ld Child=%ld\n", getpid(), child);
   return 0;
}

मेरी मशीन पर यह इस आउटपुट का उत्पादन किया:

forked! PID=3694 Child = 0
forked! PID=3696 Child = 0
forked! PID=3693 Child = 1
forked! PID=3695 Child = 1

यह कोड:

fork();
fork() && fork() || fork();
fork();

खुद के लिए 20 प्रक्रियाएं पाती हैं और 20 बार प्रिंटफ जायेगी।

और किसके लिए

fork() && fork() || fork();

printf कुल 5 बार जाएगा।





systems-programming