[ฉันจะทำซ้ำส่วนหนึ่งของคำตอบจากที่นี่ ]
ทำไมไม่เพียงแค่มีคำสั่งที่สร้างกระบวนการใหม่ตั้งแต่เริ่มต้น? มันไร้สาระและไม่มีประสิทธิภาพในการทำสำเนาที่จะถูกแทนที่ทันทีหรือไม่?
ในความเป็นจริงแล้วนั่นอาจจะไม่ได้มีประสิทธิภาพเท่าเหตุผล:
"คัดลอก" ผลิตโดยfork()
เป็นบิตของนามธรรมตั้งแต่เคอร์เนลใช้สำเนาเมื่อเขียนระบบ ; สิ่งที่ต้องสร้างจริงๆคือแผนที่หน่วยความจำเสมือน หากการคัดลอกโทรออกโดยทันทีข้อมูลexec()
ส่วนใหญ่ที่จะถูกคัดลอกหากถูกแก้ไขโดยกิจกรรมของกระบวนการไม่จำเป็นต้องคัดลอก / สร้างจริงเพราะกระบวนการไม่ทำสิ่งใด ๆ ที่ต้องการการใช้งาน
แง่มุมที่สำคัญต่าง ๆ ของกระบวนการลูก (เช่นสภาพแวดล้อม) ไม่จำเป็นต้องมีการทำซ้ำหรือตั้งเป็นรายบุคคลโดยอาศัยการวิเคราะห์ที่ซับซ้อนของบริบท ฯลฯ พวกเขาจะสันนิษฐานว่าเหมือนกับกระบวนการเรียกและ นี่คือระบบที่ใช้งานง่ายที่เราคุ้นเคย
หากต้องการอธิบายเพิ่มเติม # 1 อีกสักครู่หน่วยความจำที่ "คัดลอก" แต่ไม่เคยเข้าถึงในภายหลังจะไม่ถูกคัดลอกจริงๆอย่างน้อยที่สุดก็ในกรณีส่วนใหญ่ มีข้อยกเว้นในบริบทนี้อาจexec()
จะถ้าคุณคดเคี้ยวกระบวนการจากนั้นก็ออกจากการปกครองก่อนที่เด็กจะถูกแทนที่ด้วยตัวเองด้วย ฉันบอกว่าอาจเป็นเพราะผู้ปกครองส่วนใหญ่สามารถแคชถ้ามีหน่วยความจำว่างเพียงพอและฉันไม่แน่ใจว่าสิ่งนี้จะถูกนำไปใช้ประโยชน์เท่าไหร่ (ซึ่งขึ้นอยู่กับการใช้งานระบบปฏิบัติการ)
ของหลักสูตรที่ไม่ได้อยู่บนพื้นผิวให้ใช้สำเนาเพิ่มเติมที่มีประสิทธิภาพกว่าการใช้กระดานชนวนที่ว่างเปล่า - ยกเว้น "ชนวนว่างเปล่า" ไม่ได้เป็นตัวอักษรอะไรและต้องเกี่ยวข้องกับการจัดสรร ระบบอาจมีเทมเพลตกระบวนการว่าง / ใหม่ทั่วไปที่คัดลอกในลักษณะเดียวกัน1แต่นั่นจะไม่บันทึกอะไรเลยเทียบกับส้อมคัดลอกเมื่อเขียน ดังนั้น # 1 เพียงแสดงให้เห็นว่าการใช้กระบวนการว่างเปล่า "ใหม่" จะไม่มีประสิทธิภาพมากขึ้น
จุดที่ 2 อธิบายว่าทำไมการใช้ส้อมจึงมีประสิทธิภาพมากกว่า สภาพแวดล้อมของเด็กนั้นได้รับการถ่ายทอดมาจากพ่อแม่ ตัวอย่างเช่นหากกระบวนการหลักเป็นเชลล์และเว็บย่อยของเบราว์เซอร์$HOME
จะยังคงเหมือนเดิมสำหรับทั้งคู่ แต่เนื่องจากทั้งสองอย่างสามารถเปลี่ยนแปลงได้ในภายหลังพวกเขาจะต้องเป็นสำเนาสองชุดแยกกัน fork()
หนึ่งในเด็กที่ผลิตโดยเดิม
1. กลยุทธ์ที่อาจไม่เป็นไปตามตัวอักษร แต่ประเด็นของฉันคือการสร้างกระบวนการเกี่ยวข้องมากกว่าการคัดลอกอิมเมจลงในหน่วยความจำจากดิสก์