सी . में फोर्क सिस्टम कॉल

Fork System Call C



फोर्क () सिस्टम कॉल का उपयोग सी प्रोग्राम में चाइल्ड प्रोसेस बनाने के लिए किया जाता है। कांटा () का उपयोग किया जाता है जहां आपके आवेदन में समानांतर प्रसंस्करण की आवश्यकता होती है। कांटा () सिस्टम फ़ंक्शन को हेडर में परिभाषित किया गया है sys/types.h तथा unistd.h . एक प्रोग्राम में जहां आप फोर्क का उपयोग करते हैं, आपको प्रतीक्षा () सिस्टम कॉल का भी उपयोग करना होगा। प्रतीक्षा () सिस्टम कॉल का उपयोग मूल प्रक्रिया में बच्चे की प्रक्रिया को समाप्त करने के लिए प्रतीक्षा करने के लिए किया जाता है। चाइल्ड प्रोसेस को खत्म करने के लिए, चाइल्ड प्रोसेस में एग्जिट () सिस्टम कॉल का इस्तेमाल किया जाता है। प्रतीक्षा () फ़ंक्शन को हेडर में परिभाषित किया गया है sys/प्रतीक्षा.एच और निकास () फ़ंक्शन को हेडर में परिभाषित किया गया है stdlib.h .

चित्र 1: मूल कांटा () वर्कफ़्लो

चित्र 1: मूल कांटा () वर्कफ़्लो







इस लेख में, मैं आपको दिखाने जा रहा हूं कि सी में चाइल्ड प्रोसेस बनाने के लिए फोर्क () सिस्टम कॉल का उपयोग कैसे करें। तो, चलिए शुरू करते हैं।



कांटा () सिंटैक्स और वापसी मूल्य:

कांटा () सिस्टम फ़ंक्शन का सिंटैक्स इस प्रकार है:



pid_t कांटा(शून्य);

कांटा () सिस्टम फ़ंक्शन किसी भी तर्क को स्वीकार नहीं करता है। यह प्रकार का एक पूर्णांक देता है pid_t .





सफलता पर, fork() चाइल्ड प्रोसेस का PID लौटाता है जो कि 0 से अधिक है। चाइल्ड प्रोसेस के अंदर, रिटर्न वैल्यू 0 है। यदि fork() विफल रहता है, तो यह -1 लौटाता है।

सरल कांटा () उदाहरण:

एक साधारण कांटा () उदाहरण नीचे दिया गया है:



#शामिल
#शामिल
#शामिल
#शामिल
#शामिल

NSमुख्य(शून्य) {
pid_t pid=कांटा();

अगर(पीआईडी== 0) {
printf ('चाइल्ड => पीपीआईडी: %d पीआईडी: %dएन',गेटपीड(),गेटपीड());
बाहर जाएं (EXIT_SUCCESS);
}
अन्यथा अगर(पीआईडी> 0) {
printf ('अभिभावक => पीआईडी: %dएन',गेटपीड());
printf ('बाल प्रक्रिया समाप्त होने की प्रतीक्षा कर रहा है।एन');
रुको(शून्य);
printf ('बाल प्रक्रिया समाप्त।एन');
}
अन्यथा {
printf ('बाल प्रक्रिया बनाने में असमर्थ।एन');
}

वापसीEXIT_SUCCESS;
}

यहां, मैंने मुख्य/अभिभावक प्रक्रिया से बाल प्रक्रिया बनाने के लिए कांटा() का उपयोग किया। फिर, मैंने चाइल्ड और पैरेंट प्रोसेस से PID (प्रोसेस आईडी) और PPID (पैरेंट प्रोसेस आईडी) प्रिंट किया। मूल प्रक्रिया पर प्रतीक्षा (NULL) का उपयोग बच्चे की प्रक्रिया समाप्त होने की प्रतीक्षा करने के लिए किया जाता है। चाइल्ड प्रोसेस पर, चाइल्ड प्रोसेस को खत्म करने के लिए एग्जिट () का इस्तेमाल किया जाता है। जैसा कि आप देख सकते हैं, मूल प्रक्रिया का PID चाइल्ड प्रोसेस का PPID है। तो, बच्चे की प्रक्रिया २४७३८ मूल प्रक्रिया के अंतर्गत आता है २४७३१ .

आप अपने प्रोग्राम को अधिक मॉड्यूलर बनाने के लिए फ़ंक्शंस का भी उपयोग कर सकते हैं। यहाँ, मैंने इस्तेमाल किया प्रक्रिया कार्य () तथा पेरेंट टास्क () क्रमशः बच्चे और माता-पिता की प्रक्रियाओं के लिए कार्य करता है। इस प्रकार कांटा() वास्तव में उपयोग किया जाता है।

#शामिल
#शामिल
#शामिल
#शामिल
#शामिल

शून्यचाइल्डटास्क() {
printf ('नमस्ते दुनियाएन');
}

शून्यअभिभावक कार्य() {
printf ('मुख्य कार्य।एन');
}

NSमुख्य(शून्य) {
pid_t pid=कांटा();

अगर(पीआईडी== 0) {
चाइल्डटास्क();
बाहर जाएं (EXIT_SUCCESS);
}
अन्यथा अगर(पीआईडी> 0) {
रुको(शून्य);
अभिभावक कार्य();
}
अन्यथा {
printf ('बाल प्रक्रिया बनाने में असमर्थ।');
}

वापसीEXIT_SUCCESS;
}

उपरोक्त कार्यक्रम का आउटपुट:

फोर्क () और लूप का उपयोग करके कई चाइल्ड प्रोसेस चलाना:

आप जितनी चाहें उतनी चाइल्ड प्रोसेस बनाने के लिए लूप का उपयोग कर सकते हैं। नीचे दिए गए उदाहरण में, मैंने लूप के लिए 5 चाइल्ड प्रोसेस बनाए हैं। मैंने चाइल्ड प्रोसेस से PID और PPID भी प्रिंट किया।

#शामिल
#शामिल
#शामिल
#शामिल
#शामिल

NSमुख्य(शून्य) {
के लिये(NSमैं= 1;मैं<= 5;मैं++) {
pid_t pid=कांटा();

अगर(पीआईडी== 0) {
printf ('बाल प्रक्रिया => PPID=%d, PID=%dएन',गेटपीड(),गेटपीड());
बाहर जाएं (0);
}
अन्यथा {
printf ('मूल प्रक्रिया => पीआईडी=%dएन',गेटपीड());
printf ('चाइल्ड प्रोसेस खत्म होने का इंतजार...एन');
रुको(शून्य);
printf ('बाल प्रक्रिया समाप्त।एन');
}
}

वापसीEXIT_SUCCESS;
}

जैसा कि आप देख सकते हैं, सभी चाइल्ड प्रोसेस में पैरेंट प्रोसेस आईडी एक समान होती है। तो, वे सभी एक ही माता-पिता के हैं। वे रैखिक फैशन में भी निष्पादित करते हैं। एक के बाद एक। बाल प्रक्रियाओं को नियंत्रित करना एक परिष्कृत कार्य है। यदि आप लिनक्स सिस्टम प्रोग्रामिंग और यह कैसे काम करता है, इसके बारे में अधिक जानेंगे, तो आप इन प्रक्रियाओं के प्रवाह को अपनी पसंद के अनुसार नियंत्रित करने में सक्षम होंगे।

वास्तविक जीवन उदाहरण:

विभिन्न जटिल गणितीय गणनाओं जैसे कि md5, sha256 आदि हैश पीढ़ी के लिए बहुत अधिक प्रसंस्करण शक्ति की आवश्यकता होती है। मुख्य कार्यक्रम के समान प्रक्रिया में चीजों की गणना करने के बजाय, आप केवल एक बच्चे की प्रक्रिया पर हैश की गणना कर सकते हैं और हैश को मुख्य प्रक्रिया में वापस कर सकते हैं।

निम्नलिखित उदाहरण में, मैंने चाइल्ड प्रोसेस में 4 अंकों का पिन कोड जेनरेट किया है और इसे मुख्य प्रोग्राम, पैरेंट प्रोसेस में भेज दिया है। फिर, मैंने वहां से पिन कोड प्रिंट किया।

#शामिल
#शामिल
#शामिल
#शामिल
#शामिल

NSपिन प्राप्त करें() {
// पीपीआईडी ​​​​और पीआईडी ​​​​को बीज के रूप में उपयोग करें
सरांडो (गेटपीड() +गेटपीड());
NSगुप्त= 1000 + पंक्ति () % ९०००;
वापसीगुप्त;
}

NSमुख्य(शून्य) {
NSएफडी[2];
पाइप(एफडी);
pid_t pid=कांटा();

अगर(पीआईडी> 0) {
बंद करे(0);
बंद करे(एफडी[1]);
उपरांत(एफडी[0]);

NSगुप्त संख्या;
size_tरीडबाइट्स=पढ़ना(एफडी[0], औरगुप्त संख्या, का आकार(गुप्त संख्या));

printf ('पिन की प्रतीक्षा कर रहा है...एन');
रुको(शून्य);
printf ('बाइट्स पढ़ें: %ldएन',रीडबाइट्स);
printf (पिन: %dएन',गुप्त संख्या);
}
अन्यथा अगर(पीआईडी== 0) {
बंद करे(1);
बंद करे(एफडी[0]);
उपरांत(एफडी[1]);

NSगुप्त=पिन प्राप्त करें();
लिखो(एफडी[1], औरगुप्त, का आकार(गुप्त));
बाहर जाएं (EXIT_SUCCESS);
}

वापसीEXIT_SUCCESS;
}

जैसा कि आप देख सकते हैं, हर बार जब मैं प्रोग्राम चलाता हूं, तो मुझे एक अलग 4-अंकीय पिन कोड मिलता है।

तो, यह मूल रूप से आप लिनक्स में फोर्क () सिस्टम कॉल का उपयोग कैसे करते हैं। इस लेख को पढ़ने के लिए धन्यवाद।