वंशज की प्रक्रिया


20

मैं एक प्रक्रिया कंटेनर बनाने की कोशिश कर रहा हूं। कंटेनर अन्य कार्यक्रमों को गति देगा। उदाहरण के लिए - एक बैश स्क्रिप्ट जो पृष्ठभूमि के कार्यों को 'और' उपयोग के साथ लॉन्च करती है।

महत्वपूर्ण विशेषता यह है कि मैं इसके बाद हूं: जब मैं कंटेनर को मारता हूं, तो इसके तहत जो कुछ भी पैदा हुआ है उसे मार दिया जाना चाहिए। न सिर्फ बच्चों को, बल्कि उनके वंशजों को भी।

जब मैंने इस परियोजना को शुरू किया, तो मुझे गलती से विश्वास हो गया था कि जब आपने एक प्रक्रिया को मार दिया था तो उसके बच्चे स्वतः ही मारे गए थे। मैंने ऐसे लोगों से सलाह मांगी है जिनके पास एक ही गलत विचार था। हालांकि यह एक संकेत को पकड़ने और बच्चों को मारने पर पारित करने के लिए संभव है, वही मैं यहां नहीं देख रहा हूं।

मेरा मानना ​​है कि मैं जो हासिल करना चाहता हूं, क्योंकि जब आप एक xterm को बंद करते हैं, तो जो कुछ भी इसके भीतर चल रहा था वह तब तक मारा जाता है जब तक कि यह नॉटअप था। इसमें अनाथ प्रक्रियाएं शामिल हैं। यही मैं फिर से देखना चाहता हूं।

मेरे पास एक विचार है कि जो मैं देख रहा हूं उसमें यूनिक्स सत्र शामिल हैं।

यदि किसी प्रक्रिया के सभी वंशजों की पहचान करने का एक विश्वसनीय तरीका था, तो उन्हें मनमाने सिग्नल भेजने में सक्षम होना भी उपयोगी होगा। जैसे SIGUSR1।


ठीक है, माता-पिता की प्रक्रिया को मारना SIGHUPइसे सीधे बच्चों की प्रक्रियाओं को भेजता है। हैंग अप सिग्नल के डिफॉल्ट हैंडलर प्रक्रिया को निष्पादित करते हैं, इसलिए डिफ़ॉल्ट मार्ग सभी वंशजों को मारना है। प्रक्रियाओं और प्रक्रिया समूहों पर अधिक पढ़ें।
एलेक्स

Xterm को बंद करने से xterm में मौजूद सब कुछ नष्ट हो जाता है क्योंकि TTY नष्ट हो जाता है। यदि आप एक ट्टी बनाने के तरीके के साथ आ सकते हैं जो बच्चे की प्रक्रियाओं का उपयोग कर सकते हैं, तो आप TTY को नष्ट कर सकते हैं और उसी चीज को पूरा कर सकते हैं। कोई भी प्रक्रिया जो करीब नहीं है कि TTY (nohup & friends) को एक S नाईटअप मिलेगा।
पैट्रिक

जवाबों:


23

यदि आप किसी प्रक्रिया को संकेत भेजते हैं, तो वह प्रक्रिया मार जाती है। मुझे आश्चर्य है कि एक प्रक्रिया को मारने वाली अफवाह अन्य प्रक्रियाओं को भी मार देती है, यह विशेष रूप से काउंटर-सहज ज्ञान युक्त लगता है।

हालांकि, एक से अधिक प्रक्रियाओं को मारने के तरीके हैं। लेकिन आप एक प्रक्रिया को संकेत नहीं भेजेंगे। -1234 जहां 1234 पीजीआईडी ​​(प्रोसेस ग्रुप आईडी) है, जो कि प्रक्रिया समूह के नेता का पीआईडी ​​है, को एक सिग्नल भेजकर आप एक पूरे प्रोसेस ग्रुप को मार सकते हैं । जब आप एक पाइपलाइन चलाते हैं , तो पूरी पाइपलाइन प्रक्रिया समूह के रूप में शुरू होती है (आवेदन इसे कॉल करके setpgidया बदल सकते हैं setpgrp)।

जब आप पृष्ठभूमि में प्रक्रियाएं शुरू foo &करते हैं ( ), तो वे अपने स्वयं के प्रक्रिया समूह में होते हैं। टर्मिनल तक पहुंच का प्रबंधन करने के लिए प्रक्रिया समूहों का उपयोग किया जाता है; आमतौर पर केवल अग्रभूमि प्रक्रिया समूह में टर्मिनल तक पहुंच होती है। पृष्ठभूमि की नौकरियां एक ही सत्र में रहती हैं , लेकिन पूरे सत्र को मारने या यहां तक ​​कि एक सत्र में प्रक्रिया समूहों या प्रक्रियाओं की गणना करने के लिए कोई सुविधा नहीं है, ताकि बहुत मदद न करें।

जब आप एक टर्मिनल बंद करते हैं, तो कर्नेल उन SIGHUPसभी प्रक्रियाओं को संकेत भेजता है जो इसे उनके नियंत्रण टर्मिनल के रूप में रखती हैं । इन प्रक्रियाओं में एक सत्र होता है , लेकिन सभी सत्रों में एक नियंत्रित टर्मिनल नहीं होता है। आपकी परियोजना के लिए, एक संभावना इसलिए है कि स्क्रिप्ट , स्क्रीन आदि द्वारा बनाई गई अपने स्वयं के टर्मिनल में सभी प्रक्रियाओं को शुरू करें, निहित प्रक्रियाओं को मारने के लिए टर्मिनल एमुलेटर प्रक्रिया को मारें (यह मानते हुए कि वे साथ सुरक्षित नहीं हैं setsid)।

आप प्रक्रियाओं को अपने उपयोगकर्ता के रूप में चलाकर अधिक अलगाव प्रदान कर सकते हैं, जो कुछ और नहीं करता है। फिर सभी प्रक्रियाओं को मारना आसान है: रन kill( सिस्टम कॉल या उपयोगिता ) उस उपयोगकर्ता के रूप में और -1 को मारने के लिए पीआईडी ​​तर्क के रूप में उपयोग करें, जिसका अर्थ है "उस उपयोगकर्ता की सभी प्रक्रियाएं"।

आप और भी अलगाव प्रदान कर सकते हैं, लेकिन एक वास्तविक कंटेनर में निहित प्रक्रियाओं को चलाकर काफी अधिक सेटअप के साथ ।


: आप अपने खुद के प्रक्रियाओं कार्यक्रम है, तो आप इस तरह के रूप में कुछ प्रयोग कर सकते हैं prctl(PR_SET_PDEATHSIG, SIGHUP);:, अधिक जानकारी man7.org/linux/man-pages/man2/prctl.2.html
एलेक्सिस विके

गाइल्स, आप इसका उल्लेख करते हैं - "जब आप एक टर्मिनल बंद करते हैं, तो कर्नेल उन सभी प्रक्रियाओं को सिग्नल भेजता है जो इसे उनके नियंत्रण टर्मिनल के रूप में रखते हैं"। से इस जो आगे सत्र के भीतर सभी प्रक्रिया समूहों के लिए पर यह मैं टर्मिनल surmising कर रहा हूँ (शेल) सत्र नेता को SIGHUP भेजता है। दोनों में से कौन सही होगा?
इरुवर

4

पेरेंट स्क्रिप्ट के भीतर किल सिग्नल को फंसाते हैं और इसे सभी बच्चों को मारते हैं। उदाहरण के लिए,

#!/bin/bash
# kill the parent and children together
trap "kill 0" EXIT
# create all the children
for n in $(seq 1 100)
do
    ( echo "begin $n"; sleep 60; echo "end $n" ) &
done
# wait for the children to complete
wait

2

एक प्रक्रिया के सभी वंशजों की पहचान करने का एक विश्वसनीय तरीका है कमांड का उपयोग करना pstree <pid>जहां pid आपकी मूल प्रक्रिया आईडी है।

मैन पेज pstree यहां पढ़ें ।

किसी प्रक्रिया समूह के सभी सदस्यों को संकेत देने के लिए: killpg(<pgrp>, <sig>);
जहाँ pgrp प्रक्रिया समूह संख्या है और sig संकेत है।

एक निर्दिष्ट प्रक्रिया समूह में बच्चों की प्रतीक्षा करने के लिए: waitpid(-<pgrp>, &status, ...);

एक वैकल्पिक विकल्प जो आप कर रहे हैं वह एक नए बैश शेल में आपके प्रोसेस कंटेनर को चलाने के लिए है। कमांड के साथ नया बैश शेल बनाएं bashऔर फिर अपनी प्रक्रियाएं चलाएं। जब आप चाहते हैं कि सभी प्रक्रियाएं समाप्त हो जाएं, तो कमांड के साथ शेल से बाहर निकलें exit


मुझे लगता है कि हत्यारे मुझे वह करने की अनुमति देंगे जो मुझे करने की आवश्यकता है। धन्यवाद।
क्रेग टर्नर

1

उपयोग

unshare -fp --kill-child -- yourprogram

यदि आप मारते हैं unshare, तो सभी बाल प्रक्रियाएं (जो yourprogramशायद पैदा हो सकती हैं) को मार दिया जाएगा।

यह अब उपयोग-लिनेक्स के साथ संभव है 2.32; मैंने इस अपस्ट्रीम को लागू किया । इसके लिए यूजर नेमस्पेस (कर्नेल कॉन्फिगर विकल्प CONFIG_USER_NS=y) या रूट विशेषाधिकारों की आवश्यकता होती है। यह भी देखें यहाँ


0

rkill से आदेश pslist पैकेज संकेत (या दिए गए भेजता है SIGTERMनिर्दिष्ट प्रक्रिया और उसके सभी वंशजों को डिफ़ॉल्ट रूप से):

rkill [-SIG] pid/name...

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