वास्तविक ज़ोंबी की तरह एक ज़ोंबी प्रक्रिया को नहीं मारा जा सकता है, क्योंकि यह पहले ही मर चुका है।
यह कैसे होता है
जब लिनक्स / यूनिक्स में एक प्रक्रिया मर जाती है / समाप्त हो जाती है, तो प्रक्रिया से सभी जानकारी सिस्टम मेमोरी से हटा दी जाती है, केवल प्रक्रिया विवरणक रहता है। प्रक्रिया राज्य Z (ज़ोंबी) में मिलती है। उनकी मूल प्रक्रिया को कर्नेल से संकेत मिलता है: SIGCHLD
इसका मतलब है कि उनकी एक बच्चे की प्रक्रिया बाहर निकलती है, बाधित होती है या बाधित होने के बाद फिर से शुरू होती है (हमारे मामले में यह बस बाहर निकल जाती है)।
अभिभावक प्रक्रिया को अब wait()
अपने बच्चे की प्रक्रिया से बाहर निकलने की स्थिति और अन्य जानकारी को पढ़ने के लिए syscall को निष्पादित करना होगा । फिर वर्णनकर्ता मेमोरी से हटा दिया जाता है और यह प्रक्रिया अब एक ज़ोंबी नहीं है।
यदि पेरेंट प्रक्रिया कभी भी wait()
सिस्कॉल को नहीं बुलाती है , तो ज़ोंबी प्रक्रिया डिस्क्रिप्टर मेमोरी में रहती है और दिमाग खाती है। आम तौर पर आप ज़ोंबी प्रक्रियाओं को नहीं देखते हैं, क्योंकि ऊपर की प्रक्रिया कम समय लेती है।
मृतकों की सुबह
प्रत्येक प्रक्रिया वर्णनकर्ता को बहुत कम मात्रा में मेमोरी की आवश्यकता होती है, इसलिए कुछ लाश बहुत खतरनाक नहीं होती हैं (जैसे वास्तविक जीवन में)। एक समस्या यह है कि प्रत्येक ज़ोंबी प्रक्रिया उसकी प्रक्रिया आईडी को बनाए रखती है, और एक लिनक्स / यूनिक्स ऑपरेटिंग सिस्टम में सीमित संख्या में पिड है। यदि अनुचित तरीके से प्रोग्राम किया गया सॉफ़्टवेयर बहुत सारी ज़ोंबी प्रक्रियाएँ उत्पन्न करता है, तो ऐसा हो सकता है कि प्रक्रियाएँ अब और शुरू नहीं की जा सकती हैं क्योंकि कोई और प्रक्रिया आईडी उपलब्ध नहीं है।
इसलिए, यदि वे विशाल समूहों में हैं तो वे बहुत खतरनाक हैं (जैसे कई फिल्मों में बहुत अच्छी तरह से प्रदर्शित किया जाता है)
हम लाश की एक भीड़ के खिलाफ खुद का बचाव कैसे कर सकते हैं?
सिर में एक गोली काम करेगी, लेकिन मैं उसके लिए आदेश नहीं जानता (SIGKILL काम नहीं करेगा क्योंकि यह प्रक्रिया पहले से ही मृत है)।
ठीक है, आप माता-पिता को मारने की प्रक्रिया के माध्यम से SIGCHLD भेज सकते हैं, लेकिन जब यह इस संकेत को अनदेखा करता है, तब क्या होता है? आपका एकमात्र विकल्प माता-पिता की प्रक्रिया को मारना है और यह init प्रक्रिया ज़ोंबी को "गोद" देती है। Init wait()
अपने ज़ोंबी बच्चों को साफ करने के लिए समय-समय पर syscall कहता है ।
आपके मामले में
आपके मामले में, आपको क्रैच प्रक्रिया के लिए SIGCHLD भेजना होगा:
root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit
फिर दूसरे टर्मिनल से:
root@host:~$ kill -17 $(pgrep cron)
आउटपुट है:
restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff51be39dc, WNOHANG, NULL) = -1 ECHILD (No child processes) <-- Here it happens
rt_sigreturn(0xffffffffffffffff) = -1 EINTR (Interrupted system call)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x403170, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd6a7e9d4a0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({42, 0}, ^C <unfinished ...>
Process 1180 detached
आप wait4()
syscall रिटर्न -1 ECHILD देखते हैं , जिसका अर्थ है कि कोई भी बच्चा प्रक्रिया नहीं है। इसलिए निष्कर्ष यह है: क्रोन SIGCHLD syscall पर प्रतिक्रिया करता है और सर्वनाश के लिए मजबूर नहीं करना चाहिए।