क्या कोई यूनिक्स संस्करण है जिस पर एक बच्चे की प्रक्रिया उसके माता-पिता के साथ मर जाती है?


41

मैं पिछले कुछ समय से लिनक्स कर्नेल व्यवहार का अध्ययन कर रहा हूं, और यह मेरे लिए हमेशा स्पष्ट है:

जब एक प्रक्रिया मर जाती है, तो उसके सभी बच्चों को initप्रक्रिया (पीआईडी ​​1) को वापस दे दिया जाता है जब तक कि वे अंततः मर नहीं जाते।

हालाँकि, हाल ही में, कर्नेल के साथ मुझसे अधिक अनुभव वाले किसी व्यक्ति ने मुझे बताया कि:

जब कोई प्रक्रिया बाहर निकलती है, तो उसके सभी बच्चे भी मर जाते हैं (जब तक कि आप NOHUPकिस स्थिति में उनका उपयोग नहीं करते हैं init)।

अब, भले ही मुझे इस पर विश्वास न हो, फिर भी मैंने इसे सुनिश्चित करने के लिए एक सरल कार्यक्रम लिखा। मुझे पता है कि मुझे sleepपरीक्षणों पर समय ( ) के लिए भरोसा नहीं करना चाहिए क्योंकि यह सब प्रक्रिया निर्धारण पर निर्भर करता है, फिर भी इस सरल मामले के लिए, मुझे लगता है कि यह काफी पर्याप्त है।

int main(void){
    printf("Father process spawned (%d).\n", getpid());
    sleep(5);

    if(fork() == 0){
        printf("Child process spawned (%d => %d).\n", getppid(), getpid());
        sleep(15);
        printf("Child process exiting (%d => %d).\n", getppid(), getpid());
        exit(0);
    }

    sleep(5);
    printf(stdout, "Father process exiting (%d).\n", getpid());
    return EXIT_SUCCESS;
}

यहां कार्यक्रम का आउटपुट, संबंधित psपरिणाम के साथ हर बार printfबातचीत है:

$ ./test &
Father process spawned (435).

$ ps -ef | grep test
myuser    435    392   tty1    ./test

Child process spawned (435 => 436).

$ ps -ef | grep test
myuser    435    392   tty1    ./test
myuser    436    435   tty1    ./test

Father process exiting (435).

$ ps -ef | grep test
myuser    436    1     tty1    ./test

Child process exiting (436).

अब, जैसा कि आप देख सकते हैं, यह काफी व्यवहार करता है जैसा कि मैंने इसकी उम्मीद की होगी। अनाथ प्रक्रिया (436) initमर जाने तक (1) वापस दे दी जाती है।

हालाँकि, क्या कोई UNIX- आधारित प्रणाली है, जिस पर यह व्यवहार डिफ़ॉल्ट रूप से लागू नहीं होता है? क्या ऐसी कोई प्रणाली है जिस पर किसी प्रक्रिया की मृत्यु से उसके सभी बच्चों की मृत्यु तुरंत हो जाती है?

जवाबों:


68

जब कोई प्रक्रिया बाहर निकलती है, तो उसके सभी बच्चे भी मर जाते हैं (जब तक कि आप NOHUP का उपयोग नहीं करते हैं, उस स्थिति में वे init वापस ले लेते हैं)।

ये गलत है। एकदम गलत। यह कहने वाला व्यक्ति या तो गलत था, या सामान्य स्थिति के साथ एक विशेष स्थिति को भ्रमित करता था।

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

nohupएचयूपी संकेतों के उस दूसरे स्रोत को तोड़ने के साथ एक शेल से एक नौकरी शुरू करना क्योंकि नौकरी तब सिग्नल को अनदेखा करेगी और इस तरह टर्मिनल के गायब होने पर मरने के लिए नहीं कहा जाएगा। शेल से नौकरियों तक HUP संकेतों के प्रसार को तोड़ने के अन्य तरीकों में शेल के disownबिलिन का उपयोग करना शामिल है यदि इसमें एक है (नौकरी को शेल की सूची से हटा दिया जाता है), और डबल फोर्किंग (शेल एक बच्चे को लॉन्च करता है जो एक बच्चा लॉन्च करता है अपने स्वयं के और तुरंत बाहर निकलता है, शेल को अपने पोते का ज्ञान नहीं है)।

फिर से, टर्मिनल में शुरू की गई नौकरियां इसलिए नहीं मरतीं क्योंकि उनकी मूल प्रक्रिया (खोल) मर जाती है, बल्कि इसलिए कि उनकी माता-पिता की प्रक्रिया उन्हें मारने का फैसला करती है जब उन्हें मारने के लिए कहा जाता है। और टर्मिनल में प्रारंभिक शेल इसलिए नहीं मरता है क्योंकि इसकी मूल प्रक्रिया मर जाती है, बल्कि इसलिए कि इसका टर्मिनल गायब हो जाता है (जो संयोगवश हो सकता है या नहीं हो सकता है क्योंकि टर्मिनल एक टर्मिनल एमुलेटर द्वारा प्रदान किया जाता है जो शेल की मूल प्रक्रिया है)।


1
एक तीसरा तरीका है, नियंत्रण समूहों के साथ कुछ। मुझे सिर्फ इतना पता है कि सिस्टमड क्लीन किल को लागू करने के लिए इसका इस्तेमाल करता है।
o11c

5
@JanHudec मैं तुम्हें भ्रमित कर रहे हैं लगता है nohupके साथ disowndisownकुछ शेल में एक बिलिन है जो जॉब टेबल से एक रनिंग जॉब को हटाता है (जैसे एक तर्क ले रहा है %1), और इसका मुख्य उपयोगी साइड इफेक्ट यह है कि शेल उपप्रोसेस को SIGHUP नहीं भेजेगा। nohupएक बाहरी उपयोगिता है जो SIGHUP की उपेक्षा करती है (और कुछ अन्य चीजें करती है) फिर कमांड लाइन पर पारित कमांड को शुरू करती है।
गिल्स एसओ- बुराई को रोकना '

@ गिल्स: नहीं, मैं नहीं था, लेकिन nohupवास्तव में स्ट्रेस को देखने से पहले यह execकमांड के संकेत को अनदेखा कर देता है ।
जन हडेक

आपके उत्तर के लिए धन्यवाद! मैं विशेष रूप से मॉडेम हैंग अप के विषय में ऐतिहासिक पृष्ठभूमि से बहुत कम पसंद करता हूं। मुझे चिंता होने लगी थी कि मैं इस समय कर्नेल को गलत समझ रहा था ...
जॉन डब्ल्यूएच स्मिथ

3
यह भी ध्यान दिया जाना चाहिए कि एक कार्यक्रम तब बाहर निकलता है जब वह SIGHUP प्राप्त करता है क्योंकि S नाईटअप के लिए डिफ़ॉल्ट सिग्नल हैंडलर से बाहर निकलना है। लेकिन कोई भी कार्यक्रम अपने स्वयं के SITEUP हैंडलर को लागू कर सकता है, जो माता-पिता द्वारा इसे SITEUP भेजने पर बाहर निकलने का कारण नहीं हो सकता है।
स्लीबेटमैन

12

जब कोई प्रक्रिया बाहर निकलती है, तो उसके सभी बच्चे भी मर जाते हैं (जब तक कि आप NOHUP का उपयोग नहीं करते हैं, उस स्थिति में वे init वापस ले लेते हैं)।

यह सही है अगर प्रक्रिया सत्र का नेता है। जब एक सत्र के नेता की मृत्यु हो जाती है, तो उस सत्र के सभी सदस्यों को एक SITEUP भेजा जाता है। व्यवहार में इसका अर्थ है कि उसके बच्चे और उनके वंशज।

एक प्रक्रिया कॉल करके स्वयं को सत्र का नेता बनाती है setsid। गोले इसका उपयोग करते हैं।


मैंने अभी इस बारे में एक परीक्षण चलाया, लेकिन मैं आपके द्वारा बताए गए व्यवहार को पुन: उत्पन्न नहीं कर सका ... मैंने एक प्रक्रिया शुरू की, इसे एक नया सत्र दिया ( forkमाता-पिता की प्रक्रिया को मार डाला setsid), और इस नए सत्र में एक और बच्चे को समझा दिया। हालाँकि, जब माता-पिता की प्रक्रिया (नए सत्र के नेता) की मृत्यु हो गई, तो बच्चे को कोई साइटअप प्राप्त नहीं हुआ, और initअंततः बाहर निकलने तक संलग्न रहा ।
जॉन डब्ल्यूएच स्मिथ

से setpgid(2)मैनपेज: एक सत्र एक नियंत्रित टर्मिनल है, और कि टर्मिनल के लिए CLOCAL ध्वज सेट नहीं है, और एक टर्मिनल hangup होता है, तब सत्र नेता एक SIGHUP भेजा जाता है। यदि सत्र नेता बाहर निकलता है, तो नियंत्रण प्रक्रिया के अग्रभूमि प्रक्रिया समूह में प्रत्येक प्रक्रिया के लिए एक साइट सिग्नल भी भेजा जाएगा।
निंलज्ज

1
@ninjalj तब मुझे लगता है कि यह जवाब मान्य है कि क्या और केवल अगर सत्र नेता भी एक टर्मिनल की नियंत्रण प्रक्रिया है। एक मानक सत्र के नेता, जो किसी भी टर्मिनल से स्वतंत्र हैं, अपने बच्चों को नहीं मारेंगे। क्या यह सही है?
जॉन डब्ल्यूएच स्मिथ

-1

इसलिए उपरोक्त पोस्टर जो कह रहे हैं वह यह है कि बच्चे मरते नहीं हैं, माता-पिता उन्हें मारते हैं (या उन्हें एक संकेत भेजते हैं जिस पर वे समाप्त होते हैं)। तो आप जो पूछते हैं वह आपके पास हो सकता है, यदि आप पेरेंट टू (1) को अपने सभी बच्चों का रिकॉर्ड रखते हैं, और (2) अपने सभी बच्चों को एक संकेत भेजते हैं।

यह वही है जो शैल करता है, और यह वही होना चाहिए जो आपकी मूल प्रक्रिया करता है। माता-पिता में एचयूपी सिग्नल को पकड़ना आवश्यक हो सकता है, इसलिए आपके पास अभी भी बच्चों को मारने के लिए पर्याप्त नियंत्रण है।


कई कारणों से माता-पिता की मृत्यु हो सकती है। उदाहरण के लिए, माता-पिता SIGKILLed हैं तो बच्चों के अस्तित्व को रोकने का कोई तरीका नहीं है।
एमिल जेकाबेक मोनिका

-1

मुझे उत्तर में एक बिट याद आ रही है जो मरने वाले माता-पिता से थोड़ा संबंधित है: जब एक प्रक्रिया एक पाइप पर लिखती है जिसके लिए अब कोई पढ़ने की प्रक्रिया नहीं है, तो यह एक संकेत मिलता है। SIGPIPE के लिए मानक कार्रवाई समाप्ति है।

यह वास्तव में प्रक्रियाओं को मरने का कारण बन सकता है। वास्तव में, यह मानक तरीका है जिसमें कार्यक्रम yesमर जाता है।

अगर मैं अमल करता हूं

(yes;echo $? >&2)|head -10

मेरे सिस्टम पर, जवाब है

y
y
y
y
y
y
y
y
y
y
141

और 141 वास्तव में 128 + बड़े आकार:

   SIGPIPE      13       Term    Broken pipe: write to pipe with no
                                 readers

से man 7 signal


2
लेकिन पाइप से पढ़ने की प्रक्रिया जरूरी नहीं है (या आमतौर पर) इसके माता-पिता। इसलिए यह वास्तव में एक बहुत अलग मामला है कि सवाल किस बारे में पूछ रहा है।
बारमर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.