เมื่อฉันเคยkillall -9 name
ฆ่าโปรแกรมสถานะกลายเป็นซอมบี้ ไม่กี่นาทีต่อมามันหยุดลงจริงๆ ดังนั้นจะเกิดอะไรขึ้นในช่วงเวลาเหล่านั้น
เมื่อฉันเคยkillall -9 name
ฆ่าโปรแกรมสถานะกลายเป็นซอมบี้ ไม่กี่นาทีต่อมามันหยุดลงจริงๆ ดังนั้นจะเกิดอะไรขึ้นในช่วงเวลาเหล่านั้น
คำตอบ:
โปรแกรมไม่เคยได้รับสัญญาณ SIGKILL เนื่องจาก SIGKILL ได้รับการจัดการโดยระบบปฏิบัติการ / เคอร์เนลอย่างสมบูรณ์
เมื่อ SIGKILL สำหรับกระบวนการเฉพาะถูกส่งตัวจัดตารางเวลาของเคอร์เนลจะหยุดให้เวลาประมวลผลนั้นอีกต่อไปสำหรับการรันรหัสพื้นที่ผู้ใช้ หากกระบวนการมีเธรดใด ๆ ที่เรียกใช้งานรหัสพื้นที่ผู้ใช้บน CPUs / cores อื่น ๆ ณ เวลาที่ตัวกำหนดตารางเวลาทำการตัดสินใจนี้เธรดเหล่านั้นจะหยุดทำงานเช่นกัน (ในระบบแบบ single-core สิ่งนี้เคยง่ายกว่านี้มาก: ถ้ามี CPU core เพียงตัวเดียวในระบบที่กำลังรันตัวกำหนดตารางเวลาโดยนิยามไม่ได้ใช้กระบวนการในเวลาเดียวกัน!)
หากกระบวนการ / เธรดกำลังเรียกใช้งานรหัสเคอร์เนล (เช่นการเรียกใช้ระบบหรือการดำเนินการ I / O ที่เชื่อมโยงกับไฟล์หน่วยความจำที่แมป) ในขณะที่ SIGKILL นั้นจะได้รับบิตที่ยากขึ้น: การเรียกระบบบางอย่างจะขัดจังหวะ เคอร์เนลทำเครื่องหมายภายในกระบวนการว่าอยู่ในสถานะ "ตาย" พิเศษจนกว่าการเรียกของระบบหรือการดำเนินการ I / O จะได้รับการแก้ไข เวลาซีพียูในการแก้ไขปัญหาเหล่านั้นจะถูกกำหนดไว้ตามปกติ การเรียกใช้ระบบขัดจังหวะหรือการดำเนินการ I / O จะตรวจสอบว่ากระบวนการที่เรียกพวกเขากำลังจะตายที่จุดหยุดที่เหมาะสมและจะออกจากต้นในกรณีนั้นหรือไม่ การทำงานของ Uninterruptible จะทำงานจนเสร็จและจะตรวจสอบสถานะ "กำลังจะตาย" ก่อนที่จะกลับไปที่รหัสพื้นที่ผู้ใช้
เมื่อรูทีนเคอร์เนลในกระบวนการใด ๆ ได้รับการแก้ไขสถานะของกระบวนการจะเปลี่ยนจาก "กำลังจะตาย" เป็น "ตาย" และเคอร์เนลเริ่มล้างข้อมูลให้คล้ายกับเมื่อโปรแกรมออกจากปกติ เมื่อล้างข้อมูลเสร็จแล้วโค้ดผลลัพธ์ที่มากกว่า 128 จะถูกกำหนด (เพื่อระบุว่ากระบวนการถูกฆ่าโดยสัญญาณดูคำตอบสำหรับรายละเอียดที่ยุ่งเหยิงนี้ ) และกระบวนการจะเปลี่ยนเป็นสถานะ "ซอมบี้" . พาเรนต์ของกระบวนการที่ถูกฆ่าจะได้รับแจ้งด้วยสัญญาณ SIGCHLD
ดังนั้นกระบวนการเองจะไม่ได้รับโอกาสในการประมวลผลข้อมูลที่ได้รับ SIGKILL
เมื่อโปรเซสอยู่ในสถานะ "zombie" หมายความว่าโปรเซสนั้นตายแล้ว แต่โปรเซสหลักนั้นยังไม่ได้รับการยอมรับโดยการอ่านรหัสทางออกของกระบวนการที่ตายแล้วโดยใช้การwait(2)
เรียกระบบ โดยพื้นฐานแล้วทรัพยากรเพียงอย่างเดียวที่กระบวนการซอมบี้ใช้ไปมากคือสล็อตในตารางกระบวนการที่เก็บ PID ของตนรหัสทางออกและ "สถิติสำคัญ" อื่น ๆ ของกระบวนการในช่วงเวลาที่เสียชีวิต
หากกระบวนการผู้ปกครองเสียชีวิตก่อนที่จะมีเด็กกระบวนการเด็กกำพร้าถูกนำมาใช้โดยอัตโนมัติโดย PID # 1 ซึ่งมีหน้าที่พิเศษที่จะเรียกต่อไปเพื่อให้wait(2)
กระบวนการเด็กกำพร้าใด ๆ จะไม่ติดอยู่ในฐานะซอมบี้
หากกระบวนการซอมบี้ใช้เวลาหลายนาทีในการล้างมันแสดงให้เห็นว่ากระบวนการหลักของซอมบี้กำลังดิ้นรนหรือไม่ทำงานอย่างถูกต้อง
มีคำอธิบายแบบลิ้น - แก้มเกี่ยวกับสิ่งที่ต้องทำในกรณีที่มีปัญหาเกี่ยวกับซอมบี้ในระบบปฏิบัติการยูนิกซ์ - เหมือน: "คุณไม่สามารถทำอะไรให้กับพวกซอมบี้ตัวเองราวกับว่าพวกเขาตายแล้วแทนที่จะฆ่านายซอมบี้ชั่วร้าย! " (เช่นกระบวนการหลักของซอมบี้ที่ลำบาก)
ps
: 'S' สำหรับ I / O รอให้เคอร์เนลสามารถยกเลิกเพื่อส่งสัญญาณและ 'D' สำหรับสิ่งที่ไม่สามารถทำได้