2010-01-28 18 views
8

मैं इस कार्यक्रम के उत्पादन को समझने नहीं कर रहा हूँ के साथ काम:सी कांटा वैश्विक चर

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

int i = 0; 

int main() 
{ 
    while(i<3) 
    { 
     fork(); 

     printf("%d\n",i); 
     ++i; 
    } 
} 

उत्पादन होता है:

0 
1 
2 
2 
1 
2 
0 
1 
2 
2 
2 
1 
2 
2 

को खुश कर सकते हैं किसी को मुझे बताओ कि मैं में इस मुद्दे से निपटने चाहिए पूरी तरह समझने के लिए आदेश क्यों मुझे यह आउटपुट मिल रहा है?

+2

आपने हमें यह नहीं बताया है कि आपको इसके बारे में क्या पसंद नहीं है। – bmargulies

+0

मुझे पसंद नहीं है क्योंकि मैं समझ नहीं पा रहा हूं कि जब हम मूल प्रक्रिया या बच्चों की प्रक्रियाओं में कांटा बढ़ाते हैं। आम तौर पर अगर हम बच्चे की प्रक्रिया में वृद्धि करना चाहते हैं तो हम करते हैं (फोर्क() == 0) ++ i; लेकिन जब हम इस तरह का कांटा करते हैं, तो मुझे बीच में थोड़ा खो दिया जाता है! – Bruno

+1

उत्तर के अनुसार: बच्चे बच्चे को बढ़ाता है, माता-पिता माता-पिता बढ़ते हैं, कभी भी दो बार भोजन नहीं करेंगे। – bmargulies

उत्तर

24

फोर्क प्रक्रिया की एक प्रति बना देगा। प्रक्रिया की एक स्वतंत्र प्रति। इसलिए, यदि आपके पास फोर्क के समय वैश्विक वैरिएबल 3 होता है, तो प्रक्रिया की प्रत्येक प्रति को अपना स्वयं का 3 मिलता है। और यदि वे संशोधित होते हैं, तो उनके संशोधन पूरी तरह से स्वतंत्र होते हैं।

3

यदि आप समवर्ती प्रोग्रामिंग के लिए प्रक्रिया के अंदर एक थ्रेड बनाना चाहते हैं तो pthreads का उपयोग करने का प्रयास करें। जो फ़ंक्शन आप चाहते हैं वह बाद में tidying के लिए pthread_create और pthread_join है।

कुछ इस तरह:

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


int i = 0; 

void *threadFunc(void *arg) 
{ 
    printf("%d\n",i); 
} 

int main() 
{ 
    int j = 0; 
    int returnValue = 0; 
    pthread_t* myThread = (pthread_t*) calloc(3, sizeof(pthread_t));; 

    while(i < 3) 
    { 

     returnValue = pthread_create(&myThread[i], NULL, threadFunc, NULL); 
     printf("main thread: %d\n",i); 
     i++; 

    } 


    for(j = 0; j < 3; j++) 
    { 
     pthread_join(myThread[j], NULL); 

    } 

    return 0; 
} 

लेकिन शायद नहीं, अपने वास्तविक जरूरतों के आधार पर।

5

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

इसके प्रत्येक बच्चे fork() कॉल से प्रारंभिक i मूल्य, वृद्धि और लूपिंग को प्रिंट करके कॉल को जारी रखेंगे। इसका मतलब है कि 0 0 0, 1, और 2 प्रिंट करेंगे, और i 1 और "के प्रारंभिक" मानों के साथ दो नए बच्चों को जन्म देंगे। 2 बच्चे 1 और 2 प्रिंट करेंगे और एक "प्रारंभिक" मूल्य के साथ एक और बच्चे को जन्म देंगे i में से 2. बच्चे 2 प्रिंट करेंगे और लूप छोड़ देंगे।

यदि आप इस तर्क को जारी रखते हैं तो आप इस निष्कर्ष पर आ जाएंगे कि कुल दो 0 में, चार 1 और आठ 2 मुद्रित किए जाएंगे। लेकिन, निष्पादन का आदेश इस बात पर निर्भर करता है कि ओएस समवर्ती प्रक्रियाओं को कैसे निर्धारित करता है, आप मुद्रित किए गए आदेश पर गारंटी नहीं दे सकते हैं।

16

इस के लिए अपने कोड को बदलें और उत्पादन एक बहुत अधिक समझ बनाने चाहिए:

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 

int i = 0; 

int main() 
{ 
    while (i < 3) 
    { 
     fork(); 
     printf("pid = %d, i = %d\n", getpid(), i); 
     ++i; 
    } 
    return 0; 
} 
2

यह कुछ की तरह आदि है ...

1 (main) instance, i = 0(unforked) 
fork() > 2 instances, with i's = 0(forked), and 0(forked) 
0 output from main instance, increments its i, 2 instances with i = 1u, 0f 
main instance forks, there's 3 instances with i's 1f, 1f, 0f 
1 output from main instance, increments its i, 3 instances with i = 2u, 1f, 0f 
main instance forks, there's 4 instances with i's 2f, 2f, 1f, 0f 
2 output from main instance, increments its i, 4 instances with i = 3u, 2f, 1f, 0f 
main instance then dies, 3 instances with i = 2f, 1f, 0f 
2 output from next instance, increments its i, 3 instances with i = 3u, 1f, 0f 
next instance then dies, 2 instances with i = 1f, 0f 
1 output from next instance, increments its i to 2, 2 instances with i = 2u, 0f 

...

आदेश है कि प्रक्रियाओं में उत्पादन हो रहा है, हालांकि, अनिश्चित है, इसलिए आप हर बार सटीक उसी आउटपुट को नहीं देख पाएंगे, और यहां तक ​​कि यदि आप ऐसा करते हैं तो आप गारंटी नहीं दे सकते हैं।

जैसा कि अन्य लोगों ने कहा था, प्रत्येक प्रक्रिया का अपना वैश्विक 'i' होता है, जो इसका ट्रैक रखता है, और इसका मूल्य केवल फोर्क पर फोर्किंग प्रक्रिया का मूल्य है।

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