fork และ exec ทำงานอย่างไร


17

ฉันไม่ได้มีประสบการณ์มากนักเพียงแค่พยายามเข้ามามีส่วนร่วมในกระบวนการต่าง ๆ พวกเขาตีความถึงฮาร์ดแวร์จากระดับผู้ใช้อย่างไร

ดังนั้นเมื่อคำสั่งถูกไล่ออกจากเชลล์ให้fork()สืบทอดกระบวนการลูกของมันและexec()โหลดกระบวนการลูกไปยังหน่วยความจำและดำเนินการ

  1. หากกระบวนการลูกมีคุณลักษณะทั้งหมดของกระบวนการหลัก (ซึ่งเป็นกระบวนการดั้งเดิม) ดังนั้นความต้องการของกระบวนการลูกนี้คืออะไร? กระบวนการต้นฉบับอาจถูกโหลดไปยังหน่วยความจำ
  2. สิ่งนี้forkและexecแนวคิดนี้ใช้กับโปรแกรมปฏิบัติการทั้งหมดใน UNIX หรือไม่? ชอบเชลล์สคริปต์หรือเพียงแค่คำสั่ง? มันใช้กับคำสั่ง shell builtin หรือไม่?
  3. การคัดลอกเมื่อเขียนแนวคิดที่ใช้ถ้าฉันจะรันคำสั่ง / สคริปต์หรือไม่

ขออภัยที่ถามคำถามหลายครั้ง แต่คำถามเหล่านี้มาถึงใจของฉันทันทีเมื่อฉันคิดเกี่ยวกับการดำเนินการคำสั่งใด ๆ


ฉันจะไม่บอกว่านี่เป็นสิ่งที่ซ้ำกัน แต่ฉันคิดว่าบางคำถามของคุณได้รับคำตอบที่นี่: unix.stackexchange.com/questions/136637/ …และในคำตอบอื่น ๆ ที่ลิงก์ด้านบนของคำถามนั้น
goldilocks

คำตอบ:


22

ดังนั้นเมื่อคำสั่งถูกไล่ออกจากเชลล์ fork () สืบทอดกระบวนการลูกของมันและ exec () โหลดกระบวนการลูกไปยังหน่วยความจำและดำเนินการ

ไม่มาก fork()โคลนกระบวนการปัจจุบันสร้างชายด์ที่เหมือนกัน exec()โหลดโปรแกรมใหม่เข้าสู่กระบวนการปัจจุบันแทนที่โปรแกรมที่มีอยู่

คำถามของฉันคือ:

หากกระบวนการลูกมีคุณลักษณะทั้งหมดของกระบวนการหลัก (ซึ่งเป็นกระบวนการดั้งเดิม) ดังนั้นความต้องการของกระบวนการลูกนี้คืออะไร? กระบวนการต้นฉบับอาจถูกโหลดไปยังหน่วยความจำ

จำเป็นต้องมีเนื่องจากกระบวนการหลักยังไม่ต้องการยกเลิก มันต้องการกระบวนการใหม่ที่จะออกไปและทำอะไรบางอย่างในเวลาเดียวกันกับที่มันยังดำเนินการต่อไปเช่นกัน

แนวคิด fork และ exec นี้ใช้กับโปรแกรมปฏิบัติการทั้งหมดใน UNIX หรือไม่เช่นเดียวกับเชลล์สคริปต์หรือเฉพาะสำหรับคำสั่งเท่านั้น มันใช้กับคำสั่ง shell builtin หรือไม่?

สำหรับคำสั่งภายนอกเชลล์ทำfork()เพื่อให้คำสั่งรันในกระบวนการใหม่ บิวอินจะถูกเรียกใช้โดยเชลล์โดยตรง คำสั่งที่น่าสังเกตอีกประการหนึ่งคือexecซึ่งบอกเชลล์ให้exec()กับโปรแกรมภายนอกโดยไม่ต้องเริ่มfork()ต้น ซึ่งหมายความว่าเชลล์เองจะถูกแทนที่ด้วยโปรแกรมใหม่และจะไม่อยู่ที่นั่นเพื่อให้โปรแกรมนั้นกลับไปเมื่อออก ถ้าคุณพูดexec trueแล้ว/bin/trueจะเปลี่ยนเชลล์ของคุณและออกทันทีโดยไม่ทิ้งอะไรไว้ในเทอร์มินัลของคุณอีกต่อไปดังนั้นมันจะปิด

เมื่อใช้การคัดลอกเมื่อเขียนแนวคิดหากฉันจะรันคำสั่ง / สคริปต์?

ย้อนกลับไปในยุคหินfork()จริง ๆ แล้วต้องคัดลอกหน่วยความจำทั้งหมดในกระบวนการเรียกไปยังกระบวนการใหม่ การคัดลอกเมื่อเขียนเป็นการเพิ่มประสิทธิภาพที่มีการตั้งค่าตารางหน้าเพื่อให้กระบวนการทั้งสองเริ่มต้นจากการแชร์หน่วยความจำเดียวกันทั้งหมดและจะคัดลอกเฉพาะหน้าที่เขียนโดยกระบวนการใดกระบวนการหนึ่งเท่านั้น


4
"เกือบทุกคำสั่งเชลล์ทำ fork () เพื่อให้คำสั่งรันในกระบวนการใหม่หากคำสั่งนั้นเป็น builtin ดังนั้นเด็กไม่จำเป็นต้อง exec () โปรแกรมแยกต่างหาก" คำตอบที่ดี แต่ควรแก้ไขส่วนนี้ เชลล์ไม่แยกเมื่อรัน builtins มันรันสิ่งเหล่านั้นโดยตรงในกระบวนการเชลล์ที่ใช้งานอยู่ นี่เป็นวิธีเดียวที่ builtins เช่นcdหรือreadสามารถทำงานได้ การขาดการฟอร์กยังทำให้บิวด์อินนั้นเร็วกว่าคำสั่งภายนอก
John Kugelman สนับสนุน Monica

6
  1. สำหรับบางโปรแกรมกระบวนการลูกทำสิ่งหนึ่ง (อ่านจากพอร์ตอนุกรมเขียนไปยังเทอร์มินัล) และกระบวนการหลักดำเนินการอย่างอื่น (อ่านจากเทอร์มินัลเขียนไปยังพอร์ตอนุกรม) อีกตัวอย่างคลาสสิกคือกระบวนการของเด็กจะเป็นจุดตรวจสอบของการคำนวณระยะยาวที่เกิดขึ้น ส่วนใหญ่กระบวนการลูกทำการตั้งค่าบางอย่างเช่นการเปลี่ยนไดเรกทอรีการรีเซ็ตตัวจัดการสัญญาณหรือการรีเซ็ตตัวอธิบายไฟล์แล้วเรียกร้องexecve()ให้ซ้อนทับตัวเองด้วยรหัสที่แตกต่างกัน
  2. fork()และexec()นำไปใช้กับ executables ทั้งหมด - ในความเป็นจริงพร้อมด้วย argc และ argv และไพพ์ fork และ exec เป็นสิ่งที่แยกความแตกต่าง Unix จากระบบปฏิบัติการอื่น มีความเชี่ยวชาญเฉพาะน้อยหรือมีลักษณะทั่วไปfork()เช่น BSD's vfork(), Plan 9's rfork()และ Linux ' clone()แต่ตัวหลักยังคงเหมือนเดิม
  3. "การคัดลอกเมื่อเขียน" ไม่ได้แสดงให้ผู้ใช้เห็นจริง ๆ แล้วเป็นเทคนิคมากกว่าการเพิ่มประสิทธิภาพการสร้างกระบวนการลูกและระหว่างการดำเนินการ call stack และ heap (หน่วยความจำที่จัดสรรด้วยmalloc()หรือแม้กระทั่งตัวแปรขอบเขตคงที่หรือทั่วโลก) อาจเป็น "copy on write" เมื่อกระบวนการลูกถูกสร้างด้วยfork()การเรียกเคอร์เนลจะตั้งค่ากระบวนการลูกให้มีหน้าหน่วยความจำที่แน่นอนเหมือนกับฮีปและสแต็กเหมือนกับกระบวนการพาเรนต์ หากฮาร์ดแวร์ (หน่วยจัดการหน่วยความจำ) ตรวจพบการเขียนของกองหรือกองเคอร์เนลจะได้รับหน้าทางกายภาพใหม่ของหน่วยความจำคัดลอกหน้าของผู้ปกครองลงในหน้าใหม่และแผนที่หน้าใหม่ในกองหรือกระบวนการของเด็ก สิ่งนี้ถือเป็นการปรับให้เหมาะสมเนื่องจากเคอร์เนลใช้เวลาในการตั้งค่าการแม็พเพจน้อยกว่าการคัดลอกสแต็กและฮีปอย่างสมบูรณ์สำหรับกระบวนการลูก

ขอบคุณ Bruce สำหรับคำตอบของคุณ แต่มีหลายสิ่งที่คุณพูดที่นี่ซึ่งกำลังจะข้ามหัวฉัน ฉันไม่มีความรู้เกี่ยวกับสิ่งเหล่านี้มากนักฉันจะพยายามทำให้การทำงานของฟังก์ชั่นเหล่านี้เป็นไปตามที่คุณพูดถึง ขอบคุณมาก..!!
PriB

4
หากกระบวนการลูกมีคุณลักษณะทั้งหมดของกระบวนการหลัก (ซึ่งเป็นกระบวนการดั้งเดิม) ดังนั้นความต้องการของกระบวนการลูกนี้คืออะไร? กระบวนการต้นฉบับอาจถูกโหลดไปยังหน่วยความจำ

คำถามนี้ตอบได้อย่างชัดเจนโดยดูจากการใช้ Unix ที่เร็วที่สุดซึ่งต้องทำงานภายใต้ข้อ จำกัด ของหน่วยความจำที่รุนแรงและมีกระบวนการดำเนินการเพียงครั้งเดียวในพื้นที่หน่วยความจำ / ที่อยู่ในแต่ละครั้ง

การใช้มัลติทาสก์ทำได้โดยการสลับกระบวนการไปยังดิสก์และสลับกระบวนการที่แตกต่างกัน

ตอนนี้การforkเรียกของระบบเกือบจะเหมือนกัน: มันสลับกระบวนการออกไปยังดิสก์ แต่แทนที่จะสลับกระบวนการอื่นเข้ามาก็ให้สำเนาหน่วยความจำในกระบวนการอีกกระบวนการ id และกลับไปที่มัน และนั่นเป็นจุดที่เหมาะสมสำหรับกระบวนการนี้ในการตัดสินใจที่จะexecปฏิบัติการอื่นได้ทั้งหมด

fork+ execดังนั้นจึงไม่ได้มีค่าใช้จ่ายที่เห็นได้ชัดมากกว่าการวางไข่: คุณต้องสลับกระบวนการของคุณไปยังดิสก์ต่อไปและคุณมีอิมเมจกระบวนการเก่าในตำแหน่งหน่วยความจำที่ใช้งานได้อยู่แล้ว

ที่มีจำนวนที่เพิ่มขึ้นของหน่วยความจำและการจัดการหน่วยความจำหน่วยและหลายกระบวนการในหน่วยความจำ, ค่าใช้จ่ายเล็กน้อยแรกของส้อมกลายเป็นค่อนข้างมากรำคาญสำหรับสถาปัตยกรรมบาง: จึงvforkเกิด


2

เพื่อให้เข้าใจง่ายที่สุดฉันจะใช้การเปรียบเทียบ มาอบพายกัน!

เราหยิบหนังสือสูตรและเริ่มอ่านและนั่งบนพายผักชนิดหนึ่งสตรอเบอร์รี่ (ที่ชื่นชอบ) กับเปลือกทำด้วยมือ เกือบทุกอย่างที่เราต้องการอยู่ในครัวยกเว้นไข่และผลไม้ แต่เนื่องจากเราอยู่ในฟาร์มและผลไม้อยู่ในฤดูกาลนี่จึงไม่ใช่ปัญหา ปัญหาคือเตาอบแตกและไม่มีเวลาพอที่จะทำทุกสิ่ง จะดีกว่าไหมถ้ามีฉันมากกว่าหนึ่งคน

fork () เพื่อช่วยชีวิต ตอนนี้มีฉันสองคน และเราทั้งคู่มุ่งหน้าไปที่ห้องครัวเพื่อเริ่มทำแป้งพาย อุ่ย ดังนั้นเรามาดูผลตอบแทนจากทางแยก ฉันมีจำนวนมากเขามีศูนย์ดังนั้นฉันจึงมุ่งหน้าไปที่ห้องครัวในขณะที่เขามุ่งหน้าไปที่สุ่มไก่และสวน ขณะที่ฉันเดินผ่านเตาอบฉันก็แยก () อีกครั้งดูที่ค่าส่งคืน: คนเกียจคร้านฉันมีค่าเป็นศูนย์ เขายังคงแป้งเมื่อฉันจ้องที่เตาอบแตก ฉันเปิดประตูไม่มีไฟฉันปิดประตู ไม่มีใครรู้วิธีการแก้ไขเตาอบหรือไม่?

exec () เพื่อช่วยเหลือ ฉันไปถึงโวลต์มิเตอร์บนสายพานเครื่องมือของฉันหลอดไฟสามารถวินิจฉัยได้ดังนั้นฉันจึงตรวจสอบพลังงานเบรกเกอร์สะดุดจริง ๆ แก้ไขได้ง่าย ขณะที่ฉันเดินไปที่แผงเบรกเกอร์ฉันเห็นรูบาร์บเพื่อนคนหนึ่งกำลังหยิบ yuck! ฉันชอบช็อกโกแลตพายไหม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.