ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

ระบบปฏิบัติการเบื้องต้น

สวัสดีฮับ! ฉันอยากจะนำเสนอชุดบทความแปลของวรรณกรรมเรื่องหนึ่งที่น่าสนใจในความคิดเห็นของฉัน - OSTEP เนื้อหานี้จะตรวจสอบการทำงานของระบบปฏิบัติการที่มีลักษณะคล้ายยูนิกซ์อย่างลึกซึ้ง กล่าวคือ การทำงานกับกระบวนการ ตัวกำหนดเวลาต่างๆ หน่วยความจำ และส่วนประกอบอื่น ๆ ที่คล้ายกันซึ่งประกอบเป็นระบบปฏิบัติการสมัยใหม่ คุณสามารถดูต้นฉบับของวัสดุทั้งหมดได้ที่นี่ ที่นี่. โปรดทราบว่าการแปลจัดทำขึ้นอย่างไม่เป็นมืออาชีพ (ค่อนข้างอิสระ) แต่ฉันหวังว่าฉันจะคงความหมายทั่วไปไว้

งานห้องปฏิบัติการในเรื่องนี้สามารถพบได้ที่นี่:

ส่วนอื่น ๆ :

คุณสามารถตรวจสอบช่องของฉันได้ที่ โทรเลข =)

เตือน! มีแล็บสำหรับการบรรยายครั้งนี้! ดู GitHub

ประมวลผล API

ลองดูตัวอย่างการสร้างกระบวนการในระบบ UNIX มันเกิดขึ้นผ่านการเรียกสองระบบ ส้อม() и ผู้บริหาร ().

โทรส้อม()

ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

พิจารณาโปรแกรมที่ทำการ fork() โทร ผลลัพธ์ของการดำเนินการจะเป็นดังนี้

ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

ก่อนอื่น เราเข้าสู่ฟังก์ชัน main() และพิมพ์สตริงไปที่หน้าจอ บรรทัดนี้มีตัวระบุกระบวนการซึ่งในต้นฉบับเรียกว่า PID หรือตัวระบุกระบวนการ ตัวระบุนี้ใช้ใน UNIX เพื่ออ้างถึงกระบวนการ คำสั่งต่อไปจะเรียก fork() ณ จุดนี้ จะมีการสร้างสำเนาของกระบวนการที่เกือบจะทุกประการ สำหรับระบบปฏิบัติการ ดูเหมือนว่ามีโปรแกรมเดียวกันที่ทำงานบนระบบอยู่ 2 ชุด ซึ่งจะออกจากฟังก์ชัน fork() กระบวนการย่อยที่สร้างขึ้นใหม่ (ที่เกี่ยวข้องกับกระบวนการหลักที่สร้างขึ้น) จะไม่ถูกดำเนินการอีกต่อไป โดยเริ่มจากฟังก์ชัน main() ควรจำไว้ว่ากระบวนการย่อยไม่ใช่สำเนาที่แน่นอนของกระบวนการหลัก โดยเฉพาะอย่างยิ่ง มีพื้นที่ที่อยู่ของตัวเอง รีจิสเตอร์ของตัวเอง ตัวชี้ไปยังคำสั่งปฏิบัติการ และอื่นๆ ที่คล้ายคลึงกัน ดังนั้นค่าที่ส่งคืนไปยังผู้เรียกของฟังก์ชัน fork() จะแตกต่างกัน โดยเฉพาะอย่างยิ่ง กระบวนการหลักจะได้รับค่า PID ของกระบวนการย่อยเป็นการส่งคืน และรายการย่อยจะได้รับค่าเท่ากับ 0 เมื่อใช้โค้ดส่งคืนเหล่านี้ คุณสามารถแยกกระบวนการและบังคับให้แต่ละกระบวนการทำงานของตัวเองได้ . อย่างไรก็ตาม การทำงานของโปรแกรมนี้ไม่ได้กำหนดไว้อย่างเคร่งครัด หลังจากแบ่งออกเป็น 2 กระบวนการแล้ว OS จะเริ่มตรวจสอบและวางแผนงาน หากดำเนินการบนโปรเซสเซอร์แบบคอร์เดียว หนึ่งในกระบวนการ (ในกรณีนี้คือพาเรนต์) จะทำงานต่อไป จากนั้นกระบวนการย่อยจะได้รับการควบคุม เมื่อรีสตาร์ท สถานการณ์อาจแตกต่างกัน

รอสาย()

ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

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

ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

เรียก exec()

ระบบปฏิบัติการ: สามชิ้นง่าย ๆ ส่วนที่ 3: กระบวนการ API (การแปล)

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

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

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

การแยก fork() & exec() ช่วยให้เชลล์ทำสิ่งต่อไปนี้ได้ เช่น:
ไฟล์ wc > new_file.

ในตัวอย่างนี้ เอาต์พุตของโปรแกรม wc ถูกเปลี่ยนเส้นทางไปยังไฟล์ วิธีที่เชลล์บรรลุผลนี้ค่อนข้างง่าย - โดยการสร้างกระบวนการลูกก่อนที่จะเรียกใช้ ผู้บริหาร ()เชลล์จะปิดเอาต์พุตมาตรฐานและเปิดไฟล์ new_fileดังนั้นเอาต์พุตทั้งหมดจากโปรแกรมที่รันอยู่ต่อไป wc จะถูกเปลี่ยนเส้นทางไปยังไฟล์แทนหน้าจอ

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

ที่มา: will.com

เพิ่มความคิดเห็น