ใน UNIX เมื่อกระบวนการผู้ปกครองหายไปฉันคิดว่ากระบวนการลูกทั้งหมดรีเซ็ตการเริ่มต้นเป็นผู้ปกครอง สิ่งนี้ไม่ถูกต้องตลอดเวลาหรือไม่ มีข้อยกเว้นใด ๆ
ใน UNIX เมื่อกระบวนการผู้ปกครองหายไปฉันคิดว่ากระบวนการลูกทั้งหมดรีเซ็ตการเริ่มต้นเป็นผู้ปกครอง สิ่งนี้ไม่ถูกต้องตลอดเวลาหรือไม่ มีข้อยกเว้นใด ๆ
คำตอบ:
การย้ายความคิดเห็นของฉันไปยังคำตอบ .... ฉันไม่เชื่อว่ามีข้อยกเว้น
พบสิ่งนี้ "บางครั้งกระบวนการพาเรนต์จะถูกฆ่าก่อนที่ลูกของมันจะถูกฆ่าในกรณีนี้กระบวนการ" พาเรนต์ของกระบวนการทั้งหมด " init
จะกลายเป็น PPID ใหม่ (ID กระบวนการหลัก) บางครั้งกระบวนการเหล่านี้เรียกว่ากระบวนการเด็กกำพร้า แหล่ง
ในทำนองเดียวกันอธิบายไว้ในบล็อกของ IBM : "ผู้ปกครองตายหรือถูกฆ่าก่อนที่เด็กในสถานการณ์ข้างต้นกระบวนการเด็กกลายเป็นกระบวนการเด็กกำพร้า (ในขณะที่มันหายไปแม่) ใน Linux init
กระบวนการมาช่วยเหลือของ เด็กกำพร้าประมวลผลและนำมาใช้พวกเขาซึ่งหมายความว่าหลังจากที่เด็กได้สูญเสียผู้ปกครองของตนinit
กระบวนการกลายเป็นกระบวนการหลักของมันใหม่ "
สามคำตอบที่เขียนในปี 2014 ทุกคนบอกว่าใน Unices และใน Linux กระบวนการนั้นได้รับการซ่อมแซมในกระบวนการ # 1 โดยไม่มีข้อยกเว้น สามคำตอบที่ผิด ☺
ในฐานะที่เป็นSUSกล่าวว่าคำพูดหนึ่งในคำตอบอื่น ๆ ที่นี่ดังนั้นฉันจะไม่พูดอีกครั้งกระบวนการผู้ปกครองของเด็กกำพร้าถูกกำหนดให้เป็นกระบวนการที่กำหนดไว้ในการนำไปปฏิบัติ Cristian Ciupitu มีสิทธิ์ที่จะศึกษาเอกสารของ Linux เพื่อดูว่าการใช้งานนั้นกำหนดอย่างไร แต่เขาถูกเข้าใจผิดโดยเอกสารดังกล่าวซึ่งไม่สอดคล้องกันและไม่เป็นปัจจุบัน
สองปีก่อนเขียนคำตอบทั้งสามนี้และการเขียนคำตอบนี้อย่างรวดเร็วเมื่อสามปีก่อนเคอร์เนล Linux เปลี่ยนไป ผู้พัฒนา systemd เพิ่มความสามารถสำหรับกระบวนการในการตั้งค่าตัวเองเป็น "subreapers" จากกระบวนการ Linux 3.4 เป็นต้นไปสามารถออกการprctl()
เรียกของระบบด้วยPR_SET_CHILD_SUBREAPER
ตัวเลือกและด้วยเหตุนี้กระบวนการเหล่านี้ไม่ใช่โพรเซส 1 จะกลายเป็นพาเรนต์ของกระบวนการสืบทอดใด ๆ ของ orphaned หน้าคนสำหรับprctl()
เป็น up-to-date, แต่หน้าคนอื่น ๆ ที่ยังไม่ได้ถูกนำมาถึงวันที่และทำให้สอดคล้องกัน
ในเวอร์ชั่น 10.2 FreeBSD ได้รับความสามารถเดียวกันโดยขยายการprocctl()
เรียกระบบที่มีอยู่ด้วยPROC_REAP_ACQUIRE
และPROC_REAP_RELEASE
ตัวเลือกต่างๆ มันใช้กลไกนี้จาก DragonFly BSD; ซึ่งได้รับความไว้ในรุ่น 4.2 ชื่อเดิมแต่เปลี่ยนชื่อในระหว่างการพัฒนาเพื่อ reapctl()
procctl()
ดังนั้นจึงมีข้อยกเว้นและสิ่งที่โดดเด่นพอสมควร: บน Linux, FreeBSD / PC-BSD และ DragonFly BSD กระบวนการหลักของเด็กกำพร้าถูกตั้งค่าเป็นกระบวนการบรรพบุรุษที่ใกล้ที่สุดของเด็กที่ถูกทำเครื่องหมายว่าเป็นรายงานย่อยหรือกระบวนการ # 1 หากไม่มีกระบวนการย่อยรายงานย่อยบรรพบุรุษ ยูทิลิตีการควบคุมดูแล daemon ต่างๆ - รวมถึง systemd (ผู้พัฒนาที่ใส่สิ่งนี้ลงในเคอร์เนล Linux ตั้งแต่แรก) พุ่งพรวดและ nosh service-manager
- ใช้ประโยชน์จากสิ่งนี้แล้ว
หากผู้ดูแล daemon นั้นไม่ได้ดำเนินการ # 1 และจะให้บริการเช่นเซสชันการเข้าสู่ระบบแบบอินเทอร์แอคทีฟและในเซสชั่นนั้นจะทำการหลอกลวงfork()
ไอเอ็นจีแล้วกระบวนการหนึ่งของจะ ลงเอยด้วยการเป็นลูกของผู้ดูแล daemon ไม่ใช่กระบวนการ # 1 คาดว่าจะสามารถวางไข่ daemons โดยตรงจากภายในเซสชันการเข้าสู่ระบบเป็นข้อผิดพลาดพื้นฐานแน่นอน แต่นั่นเป็นคำตอบอื่น
procctl()
. คู่มือการใช้งาน DragonFly BSD § 2จากexit
หน้า man จากข้อมูลจำเพาะของUNIX®เดียว, เวอร์ชัน 2:
ID กระบวนการหลักของกระบวนการลูกที่มีอยู่ทั้งหมดของกระบวนการลูกที่มีอยู่และกระบวนการ zombie ถูกตั้งค่าเป็น ID กระบวนการของกระบวนการระบบที่ขึ้นอยู่กับการนำไปใช้งาน กล่าวคือกระบวนการเหล่านี้สืบทอดมาจากกระบวนการระบบพิเศษ
สำหรับตัวแปร Unix ส่วนใหญ่กระบวนการพิเศษนั้นคือinit
(PID 1)
wait(2)
หน้าลินุกซ์ยืนยันสิ่งนี้:
หากกระบวนการหลักยุติลงจะมีการใช้ลูก "zombie" (ถ้ามี) ของ init (8) ซึ่งจะทำการรอเพื่อลบซอมบี้โดยอัตโนมัติ
หน้าคน FreeBSD wait(2)
, NetBSD wait(2)
, OpenBSD wait(2)
และ Mac OS X wait(2)
ยืนยันสิ่งนี้เช่นกัน:
หากกระบวนการพาเรนต์สิ้นสุดลงโดยไม่ต้องรอให้กระบวนการลูกทั้งหมดยุติกระบวนการลูกที่เหลือจะได้รับการกำหนดกระบวนการหลัก 1 ID (ID กระบวนการเริ่มต้น)
wait(3C)
เพจ man ของOracle Solaris 11.1 ยืนยันสิ่งนี้ด้วย:
หากกระบวนการพาเรนต์สิ้นสุดลงโดยไม่ต้องรอให้กระบวนการย่อยสิ้นสุดลง ID กระบวนการหลักของกระบวนการลูกแต่ละกระบวนการจะถูกตั้งค่าเป็น 1 โดยกระบวนการเริ่มต้นจะสืบทอดกระบวนการลูกนั้น เห็น
Intro(2)
ไหม
ฉันไม่เชื่ออย่างนั้น มันจะไปที่กระบวนการเริ่มต้นเสมอ