2009-07-21 11 views
28

बच्चों की प्रक्रियाओं के लिए, wait() और waitpid() फ़ंक्शंस का उपयोग वर्तमान प्रक्रिया के निष्पादन को निलंबित करने के लिए किया जा सकता है जब तक कि कोई बच्चा निकल न जाए। लेकिन इस समारोह का उपयोग गैर-बाल प्रक्रियाओं के लिए नहीं किया जा सकता है।गैर-बच्चों की प्रक्रियाओं से बाहर निकलने के लिए कैसे प्रतीक्षा करें

क्या कोई और कार्य है, जो किसी भी प्रक्रिया से बाहर निकलने के लिए इंतजार कर सकता है?

उत्तर

25

wait() के बराबर कुछ भी नहीं। सामान्य अभ्यास kill(pid, 0) का उपयोग करके मतदान करना है और प्रक्रिया को समाप्त करने के संकेत देने के लिए ESRCH के वापसी मूल्य -1 और errno की तलाश करना है।

+2

क्या यह व्यस्त लूप होना ठीक है? – CsTamas

+1

ठीक है, आप इसे बहुत व्यस्त नहीं बनाना चाहते हैं; प्रत्येक 'हत्या()' के बाद आपको थोड़ी देर के लिए 'नींद() 'चाहिए, जो प्रक्रिया को नहीं मिला है। फिर आपको अपने मतदान में कितना व्यस्त है और नोटिस करने से पहले प्रक्रिया को समाप्त करने के लिए कितना समय ठीक है, इसके बीच संतुलन को रोकना होगा। – chaos

+0

ओह, 'नींद()' अप्रचलित हो गया, जबकि मैं स्पष्ट रूप से नहीं देख रहा था। ऐसा लगता है कि आपको अब 'नैनोस्लीप()' चाहिए। – chaos

2

कोई भी मुझे पता नहीं है। अराजकता के समाधान के अलावा, आप सेमफोर का उपयोग कर सकते हैं यदि आप उस प्रोग्राम को बदल सकते हैं जिसके लिए आप प्रतीक्षा करना चाहते हैं।

पुस्तकालय कार्यों sem_open(3), sem_init(3),sem_wait(3), ... हैं

sem_wait(3), एक प्रतीक्षा करता है ताकि आप chaos' समाधान में के रूप में व्यस्त प्रतीक्षा करना है नहीं है। बेशक, सेमफोर का उपयोग करके आपके कार्यक्रम अधिक जटिल होते हैं और यह समस्या के लायक नहीं हो सकता है।

+0

ये सेमफोर वर्चुअल रूप से बेकार हैं, क्योंकि वे तब भी जारी रहते हैं जब कोई प्रक्रिया खुलती न हो। मुझे कुछ दुर्घटनाग्रस्त प्रक्रिया के बचे हुए पदार्थों को साफ करने के लिए आईपीसीआरएम को कॉल करने के लिए समय-समय पर याद रखना याद है। –

4

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

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

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

+2

लेकिन प्रक्रिया एक बच्चा नहीं है ... – LtWorf

+0

कोई बच्चा नहीं है और विशेष रूप से इसे इस ट्रैकिंग के साथ दिमाग में डिज़ाइन नहीं किया जा सकता है और स्रोत कोड को संशोधित करने में सक्षम नहीं है। – Lothar

+0

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

1

शायद गायब होने के लिए/proc/[pid] या/proc/[pid]/[कुछ] के लिए प्रतीक्षा करना संभव हो सकता है?

मतदान() और अन्य फ़ाइल ईवेंट प्रतीक्षा फ़ंक्शन हैं, शायद इससे मदद मिल सकती है?

+0

हां, यह एक अच्छा विचार है। जब तक एक ही प्रक्रिया आईडी का पुन: उपयोग नहीं किया जाता है - लेकिन शायद यह शायद ही कभी – CsTamas

+0

@CsTamas होता है, वहां सुरक्षा है जहां प्रक्रिया पहचानकर्ताओं की संख्या (32768) चलने वाली प्रक्रियाओं की संख्या से काफी बड़ी है। तो जब तक आप थोड़ी देर के लिए सोते हैं, तब तक आपको वही प्रक्रिया पहचानकर्ता प्राप्त करने की संभावना वास्तव में कम होती है। –

3

आप ptrace(2) के साथ प्रक्रिया से संलग्न हो सकते हैं। खोल से, strace -p PID >/dev/null 2>&1 काम करने लगता है। यह व्यस्त प्रतीक्षा से बचता है, हालांकि यह पता लगाए गए प्रक्रिया को धीमा कर देगा, और सभी प्रक्रियाओं पर काम नहीं करेगा (केवल आपका, जो केवल बाल प्रक्रियाओं से थोड़ा बेहतर है)।

+1

ज्ञान कभी नुकसान नहीं पहुंचाता है, लेकिन गोले के लिए, मैं "मानक" तरीके की सिफारिश करता हूं, समय-समय पर मतदान; [प्रश्न 1058047] देखें (http://stackoverflow.com/questions/1058047/wait-for-any-process-to-finish)। हालांकि यह एक दुर्लभ मामला हो सकता है, लेकिन स्ट्रेस व्यस्त लूप बना सकता है। जैसे $ (पढ़ें) &; strace -p $!ध्यान दें कि (पढ़ा) और खुद निर्दोष है। –

12

बीएसडी और ओएस एक्स पर, आप वास्तव में ऐसा करने के लिए EVFILT_PROC + NOTE_EXIT के साथ kqueue का उपयोग कर सकते हैं। कोई मतदान की आवश्यकता नहीं है। दुर्भाग्य से कोई लिनक्स समकक्ष नहीं है।

+5

लिनक्स पर शर्मिंदा है कि उन्होंने kqueue पोर्ट नहीं किया है। – Lothar

6

अब तक मैं तीन तरीके लिनक्स पर यह करने के लिए मिल गया है:

  • मतदान: यदि आप हर बार प्रक्रिया के होने की जाँच, या तो kill का उपयोग करके या /proc/$pid के अस्तित्व के लिए परीक्षण द्वारा इस तरह से -, अन्य उत्तर के अधिकांश में के रूप में
  • एक डिबगर तरह की प्रक्रिया के लिए संलग्न करने के लिए ptrace सिस्टम कॉल का उपयोग करें ताकि आप सूचित कर दिया जब यह बाहर निकालता है a3nm's answer
  • उपयोग के रूप में, netlink इंटरफ़ेस PROC_EVENT_EXIT संदेशों के लिए सुनने के लिए कश्मीर जब भी कोई प्रक्रिया निकलती है तो कर्नेल आपके प्रोग्राम को बताता है और आप बस सही प्रक्रिया आईडी की प्रतीक्षा करते हैं। मैंने इसे केवल in one place on the internet वर्णित देखा है।

बेकार प्लग: मैं program (कोर्स का खुला स्रोत; जीपीएलवी 2) पर काम कर रहा हूं जो तीनों में से कोई भी करता है।

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