एक ज़ोंबी अपने बच्चे की प्रतीक्षा क्यों कर रही है?


11

मैं विभिन्न स्रोतों के माध्यम से खुदाई कर रहा हूं, लेकिन बच्चे के काटने की शारीरिक रचना का अच्छा विवरण नहीं पा रहा हूं। यह एक साधारण मामला है जिसे मैं समझना चाहूंगा।

$ cat <( sleep 100 & wait ) &
[1] 14247
$ ps ax -O pgid | grep $$
12126 12126 S pts/17   00:00:00 bash
14248 12126 S pts/17   00:00:00 bash
14249 12126 S pts/17   00:00:00 sleep 100
14251 14250 S pts/17   00:00:00 grep --color=auto 12126
$ kill -2 14248

$ ps ax -O pgid | grep $$
12126 12126 S pts/17   00:00:00 bash
14248 12126 Z pts/17   00:00:00 [bash] <defunct>
14249 12126 S pts/17   00:00:00 sleep 100
14255 14254 S pts/17   00:00:00 grep --color=auto 12126

बच्चे का इंतजार क्यों कर रहा है लाश?

क्या आप इसे समझा सकते हैं? क्या मुझे इस बारे में व्यापक समझ प्राप्त करने के लिए C और Bash स्रोत कोड जानने की आवश्यकता है या कोई प्रलेखन है? मैंने पहले ही सलाह ली है:

GNU बैश, संस्करण 4.3.42 (1) -release (x86_64-pc-linux-gnu)

लिनक्स 4.4.0-31-जेनेरिक # 50-उबंटू एसएमपी बुध जुलाई 13 00:07:12 यूटीसी 2016 x86_64 x86_64 x86_64 GNU / लिनक्स


2
ध्यान रखना चाहिए कि इसका वास्तव में बैश से कोई लेना-देना नहीं है (इस तथ्य के अलावा कि यदि आप अपने शेल के रूप में बैश का उपयोग करना चुनते हैं, तो इसके द्वारा बहुत सारी प्रक्रियाएं शुरू हो जाएंगी)। अन्य गोले (tsh, ksh, zsh, और c) सभी प्रक्रियाएँ शुरू करते हैं, और अनिवार्य रूप से उनसे निपटने के लिए समान OS फ़ंक्शन चलाते हैं।
jamesqf

@jamesqf दिलचस्प। यदि आप अपनी टिप्पणी का पूरी तरह से उत्तर देना चाहते हैं, तो यह बहुत अच्छा होगा।

1
सिवाय इसके कि यह वास्तव में एक उत्तर नहीं है, केवल यह इंगित करता है कि आप गलत स्थानों पर उत्तर की तलाश कर रहे हैं :-) * * nix सिस्टम प्रोग्रामिंग पर कोई भी अच्छी पुस्तक मुझे लिखने से बेहतर उत्तर प्रदान करना चाहिए।
jamesqf

जवाबों:


17

ज़ोंबी अपने बच्चे के लिए इंतजार नहीं कर रहा है। किसी भी ज़ोंबी प्रक्रिया की तरह, यह तब तक रहता है जब तक कि इसके माता-पिता इसे इकट्ठा नहीं करते।

आपको यह समझने के लिए कि क्या हो रहा है, और पीपीआईडी ​​को देखने के लिए इसमें शामिल सभी प्रक्रियाओं को प्रदर्शित करना चाहिए। इस कमांड लाइन का उपयोग करें:

ps -t $(tty) -O ppid,pgid

जिस प्रक्रिया को आप मार रहे हैं उसका जनक है cat। क्या होता है कि बैश cat <( sleep 100 & wait )एक उपशीर्ष में पृष्ठभूमि कमांड चलाता है । चूँकि यह सबस्क्रिप्शन केवल एकमात्र चीज़ है, इसलिए कुछ पुनर्निर्देशन स्थापित करना और फिर एक बाहरी कमांड चलाना, इस सबस्क्रिप्शन को बाहरी कमांड द्वारा बदल दिया जाता है। यहाँ रंडी है:

  • मूल बैश (12126) एक बच्चे (14247) में forkपृष्ठभूमि कमांड को निष्पादित करने के लिए कहता है cat <( sleep 100 & wait )
    • बच्चा (14247) pipeएक पाइप बनाने के लिए कॉल करता है, फिर forkप्रक्रिया प्रतिस्थापन को चलाने के लिए एक बच्चा बनाने के लिए sleep 100 & wait
      • पोते (14248) को पृष्ठभूमि में forkचलने के लिए कहता है sleep 100। चूंकि पोता इंटरैक्टिव नहीं है, पृष्ठभूमि प्रक्रिया एक अलग प्रक्रिया समूह में नहीं चलती है। फिर पोता sleepबाहर निकलने का इंतजार करता है ।
    • बच्चे (14247) कॉल setpgid(यह एक इंटरैक्टिव शेल में एक पृष्ठभूमि का काम है, इसलिए इसे अपना स्वयं का प्रक्रिया समूह मिलता है), फिर execveचलाने के लिए cat। (मैं थोड़ा हैरान हूँ कि प्रक्रिया प्रतिस्थापन पृष्ठभूमि प्रक्रिया समूह में नहीं हो रहा है।)
  • आप पोते (14248) को मार डालते हैं। इसका अभिभावक चल रहा है cat, जो किसी भी बच्चे की प्रक्रिया के बारे में कुछ नहीं जानता है और कोई भी व्यावसायिक कॉलिंग नहीं है wait। चूंकि पोते के माता-पिता उसे नहीं काटते, इसलिए पोता एक ज़ोंबी के रूप में पीछे रहता है।
  • आखिरकार, catबाहर निकलता है - या तो क्योंकि आप इसे मारते हैं, या क्योंकि sleepरिटर्न और पाइप को बंद कर देता है इसलिए catइसके इनपुट के अंत को देखता है। उस बिंदु पर, ज़ोंबी के माता-पिता की मृत्यु हो जाती है, इसलिए ज़ोंबी को init द्वारा एकत्र किया जाता है और init इसे फिर से पढ़ता है।

यदि आप कमांड को बदलते हैं

{ cat <( sleep 100 & wait ); echo done; } &

फिर catएक अलग प्रक्रिया में चलता है, मूल बैश प्रक्रिया के बच्चे में नहीं: पहले बच्चे को दौड़ने के लिए पीछे रहना पड़ता है echo done। इस मामले में, यदि आप पोते को मारते हैं, तो यह एक ज़ोंबी के रूप में नहीं रहता है, क्योंकि बच्चा (जो उस बिंदु पर अभी भी चल रहा है) इसे पढ़ता है।

यह भी देखें कि लिनक्स कैसे ज़ोंबी प्रक्रिया को संभालता है और क्या एक ज़ोंबी अनाथ हो सकता है? क्या अनाथ बच्चों को ज़ोंबी काटकर परेशान किया जाएगा?


मुझे प्रक्रिया समूह की बात पर भी आश्चर्य हुआ। ऐसा लग रहा है कि यह एक बग था और यह अब बैश मास्टर शाखा में तय हो गया है।
PSkocik

"मूल बैश अपने बच्चे (14247) की प्रतीक्षा कर रहा है।" क्यों या किस तरीके से? बच्चे को पृष्ठभूमि में चलना चाहिए और कोई स्पष्ट कॉल नहीं है। 14247 और 14247 (जो चल रहा है cat) 14248 की प्रतीक्षा नहीं कर रहा है (प्रतीक्षा कर रहा है ) के लिए मूल बैश (14246) में क्या अंतर है sleep? क्या कोई स्मृति है कि किसकी प्रतीक्षा होती है, जिसे बच्चा (14247) खो देता है और मूल बैश (14246) नहीं होता है, या शायद SIGCHLD जैसे संकेतों की एक सूची जिसे बुलाया जाना चाहिए और 14247 (अब चल रहा है bash) के साथ सदस्यता समाप्त 14248 के संबंध में?

1
@ टोमस का मतलब था कि मूल बैश waitउसके बच्चे को बुलाता है , अर्थात वह उसे पढ़ता है। मैं देख सकता हूं कि यह कैसे भ्रामक होगा, मैंने उस वाक्य को हटा दिया है जो सही समय पर भी नहीं बोल रहा था। किसी प्रक्रिया के मर जाने की जानकारी उस प्रक्रिया के जनक को जाती है, एक प्रक्रिया किसी अन्य प्रक्रिया की मृत्यु के बारे में जानकारी प्राप्त करने के लिए "सदस्यता" नहीं ले सकती है।
गिलेस एसओ- बुराई को रोकना '

6

ज़ोंबी बच्चे की प्रतीक्षा नहीं कर रहा है। इसके बजाय, ज़ोंबी है प्रक्रिया है कि पहले से ही (अपने स्वयं के द्वारा, या मारा गया था - अपने उदाहरण के रूप में) की मृत्यु हो गई, उसका कोड, डेटा था और ढेर पुनः आवंटित की जाती है, और अब केवल अपनी मूल कॉल करने के लिए के लिए इंतज़ार कर अपने से बाहर निकलें कोड होता है, इसे पुनः प्राप्त करने (और इस प्रकार अंत में प्रक्रिया तालिका से पूरी तरह से साफ प्रक्रिया प्रविष्टि)wait(2)

आपके उदाहरण में, जब नींद खत्म हो जाती है (या मार दिया जाता है), तो माता-पिता बाहर निकलने की स्थिति पढ़ेंगे, और लाश को काटेंगे। ऊपर देखें wait(2)विवरण के लिए।

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