2012-01-23 13 views
7

मुझे समझ गया है कि: 1) प्रतीक्षापिड का उपयोग बच्चे की मौत की प्रतीक्षा करने के लिए किया जाता है और फिर सिगचल और बच्चे के बाहर निकलने की स्थिति आदि एकत्रित किया जाता है। 2) जब हमारे पास सिगचल के लिए सिग्नल हैंडलर होता है, तो हम कुछ और चीजें करते हैं बच्चे या अन्य सामान (प्रोग्रामर तक) के सफाई से संबंधित है और फिर एक प्रतीक्षापैड करें ताकि बच्चा ज़ोंबी नहीं जायेगा और फिर वापस आ जाएगा।प्रतीक्षापिड या सिग्नेक्शन का उपयोग कर?

अब, क्या हमारे पास हमारे कार्यक्रमों में 1 और 2 दोनों होने की आवश्यकता है जब हम एक कांटा/निष्पादन करते हैं और बच्चे वापस आते हैं? हम दोनों है, तो SIGCHLD पहले प्राप्त किया जाता है, तो संकेत हैंडलर पहले कहा जाता है और इस तरह अपनी waitpid सफलतापूर्वक कहा जाता है और माता-पिता की प्रक्रिया कोड में नहीं waitpid इस प्रकार है:

my_signal_handler_for_sigchld 
{ 
do something 
tmp = waitpid(-1,NULL,0); 
print tmp (which is the correct value of the child pid) 
} 

int main() 
{ 
    sigaction(SIGCHLD, my_signal_handler_for_sigchld) 
    fork() 
    if (child) //do something, return 
    if parent // waitpid(child_pid, NULL,0); print value returned from this waitpid - it is -1 
} 

की सराहना करता है, तो किसी ने मुझे मदद करता है इसे समझो

उत्तर

1

आपको waitpid या दोस्तों -0 wait4 इत्यादि के प्रतीक्षा पाठ्यक्रमों को कॉल करने की आवश्यकता है - अन्यथा आपके पास zombie processes हो सकता है।

आप SIGCHLD को यह सूचित करने के लिए संभाल सकते हैं कि कुछ बच्चा समाप्त हो गया है (या बंद कर दिया गया है ...) लेकिन आपको बाद में इसके लिए इंतजार करना होगा।

सिग्नल हैंडलर एसिंक-सिग्नल-सुरक्षित-कार्यों के एक छोटे सेट को कॉल करने के लिए प्रतिबंधित हैं (अधिक के लिए signal(7) देखें)। अच्छी सलाह है कि volatile sig_atomic_t ध्वज को अंदर सेट करें, और बाद में और सुरक्षित स्थानों पर इसका परीक्षण करें।

18

यदि आपका इरादा बाल प्रक्रिया चलाने के लिए है, तो कुछ सामान करें, फिर इसे पूरा करने के लिए प्रतीक्षा करें, तो आपको वास्तव में SIGCHLD को संभालने की आवश्यकता नहीं है। उस स्थिति में, जब आप सिंक्रनाइज़ करने के लिए तैयार हों तो आप waitpid पर कॉल करें। एकमात्र चीज SIGCHLD बाल समाप्ति की असीमित अधिसूचना के लिए उपयोगी है, उदाहरण के लिए यदि आपके पास एक इंटरैक्टिव (या लंबे समय से चलने वाला डिमन) एप्लिकेशन है जो विभिन्न बच्चों को पैदा कर रहा है और उन्हें समाप्त होने के बारे में जानने की आवश्यकता है। हालांकि, इस उद्देश्य के लिए SIGCHLD वास्तव में खराब/बदसूरत है, क्योंकि यदि आप लाइब्रेरी कोड का उपयोग कर रहे हैं जो बाल प्रक्रियाओं को बनाता है, तो आप पुस्तकालय के बच्चों को समाप्त करने और उनके संचालन में दखल देने के लिए घटनाओं को पकड़ सकते हैं। सिग्नल हैंडलर स्वाभाविक रूप से प्रक्रिया-वैश्विक हैं और वैश्विक स्थिति से निपटते हैं, जो आम तौर पर एक खराब बात (टीएम) होता है।

यहाँ आप बच्चे प्रक्रियाओं है जब के लिए दो बेहतर दृष्टिकोण है कि अतुल्यकालिक रूप से समाप्त कर देगा कर रहे हैं:

दृष्टिकोण 1 (select/poll घटना पर आधारित): सुनिश्चित करें कि आप एक पाइप/प्रत्येक बच्चे प्रक्रिया से आप बनाने के लिए सुनिश्चित करें । यह या तो उनके stdin/stdout/stderr या सिर्फ एक अतिरिक्त डमी एफडी हो सकता है। जब बच्चे की प्रक्रिया समाप्त हो जाती है, तो पाइप का अंत बंद हो जाएगा, और आपका मुख्य ईवेंट लूप उस फ़ाइल डिस्क्रिप्टर पर गतिविधि का पता लगाएगा। तथ्य यह है कि यह बंद हो गया है, आप पहचानते हैं कि बच्चे की प्रक्रिया की मृत्यु हो गई है, और ज़ोंबी काटने के लिए waitpid पर कॉल करें।

दृष्टिकोण 2 (थ्रेड आधारित): आपके द्वारा बनाई गई प्रत्येक बाल प्रक्रिया के लिए, एक धागा भी बनाएं जो तुरंत बच्चे की प्रक्रिया के पिड पर waitpid पर कॉल करेगा। जब waitpid सफलतापूर्वक लौटता है, तो अपने पसंदीदा थ्रेड सिंक्रनाइज़ेशन प्राइमेटिव का उपयोग करें ताकि बाकी कार्यक्रम को पता चले कि बच्चे को समाप्त कर दिया गया है, या बस इसे समाप्त करने से पहले इस वेटर थ्रेड में आपको जो कुछ भी करने की ज़रूरत है उसका ख्याल रखना है।

इन दोनों दृष्टिकोण मॉड्यूलर और लाइब्रेरी-अनुकूल हैं (वे आपके कोड या पुस्तकालय कोड के किसी अन्य भाग में दखल देने से बचते हैं जो बाल प्रक्रियाओं का उपयोग कर सकता है)।

+0

हाय, आपके उत्तर के लिए धन्यवाद।लेकिन मैं वास्तव में क्या देख रहा था: जब मेरे पास दोनों प्रक्रियाओं में sig_handler और waitpid है, तो sig_handler को सिग्चल्ड के becaues कहा जाता है और फिर दूसरा प्रश्नपत्र मेरे प्रश्न रिटर्न -1 में ऊपर दिखाया गया है। तो क्या मैं सिर्फ 2 वेटपिप को हटा सकता हूं जो मेरे पास है? – Vin

+0

हां, आप केवल एक बार दिए गए बच्चे की प्रक्रिया के लिए सफलतापूर्वक प्रतीक्षा कर सकते हैं। वास्तव में यह प्रतीक्षा करने के लिए एक बग है क्योंकि पिड पहले इंतजार से "मुक्त" होता है और शायद एक नई बाल प्रक्रिया के लिए पुन: उपयोग किया जा सकता है (यदि आप एक और बनाते हैं)। –

+0

@ आर .. क्या हम स्पष्ट कर सकते हैं कि जब बच्चे की प्रक्रिया समाप्त हो जाती है, तो पाइप का अंत बंद हो जाएगा? वास्तव में सटीक होने के लिए, यह नहीं होगा 'जब बच्चा प्रक्रिया अपने एफडी को बंद कर देती है जो पाइप के अंत से जुड़ा हुआ है, और उस पाइप के अंत से जुड़े एफडी को कोई अन्य प्रक्रिया नहीं है, तो पाइप का दूसरा छोर होगा बंद के रूप में संकेत (ईओएफ प्राप्त) '? मेरा मानना ​​है कि जो कुछ भी होता है, उसे और अधिक स्पष्ट रूप से समझाएगा, और यदि 2 से अधिक प्रक्रियाएं पाइप को एक पाइप खोलने के लिए होती हैं तो इसका महत्वपूर्ण विशेष मामला भी होता है। – nh2

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