เมื่อใดที่คำสั่งในตัวถูกโหลดเข้าสู่หน่วยความจำ


11

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


1
ฉันคิดว่าคำตอบนี้จะช่วยให้คุณเข้าใจแม้ว่าจะไม่ซ้ำกันมากนัก
cjm

@cjm: ขอบคุณมันเป็นคำอธิบายที่ดีในการอ่าน
Forethinker

คำตอบ:


9

สมมุติว่าฉันพิมพ์ cd ลงใน shell ซีดีถูกโหลดจากหน่วยความจำในขณะนั้นหรือไม่? สัญชาตญาณของฉันคือคำสั่งในตัวเหล่านี้ถูกโหลดล่วงหน้าไปยังหน่วยความจำระบบหลังจากเคอร์เนลถูกโหลด แต่มีคนยืนยันว่าพวกเขาจะถูกโหลดเมื่อฉันเรียกใช้คำสั่งจริงเท่านั้น ...

ในแง่กว้างคำตอบอื่น ๆ ที่ถูกต้อง - ในตัวจะเต็มไปด้วยเปลือกหอยแบบสแตนด์อโลนจะถูกโหลดเมื่อเรียก อย่างไรก็ตามการพังพอนอย่างเหนียวแน่น "คน" สามารถยืนยันได้ว่ามันไม่ง่ายเลย

การสนทนานี้ค่อนข้างเกี่ยวกับการทำงานของระบบปฏิบัติการและวิธีการทำงานของ OS ที่แตกต่างกัน แต่ฉันคิดว่าโดยทั่วไปแล้วสิ่งต่อไปนี้น่าจะเป็นจริงสำหรับ nixes ร่วมสมัยทุกคน

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

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

ตัวอย่างเช่นต่อไปนี้เป็นตัวอย่างของtopเอาต์พุตบน linux ที่อ้างถึงbashอินสแตนซ์:

VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                  
113m 3672 1796 S  0.0  0.1   0:00.07 bash   

VIRT 113 MB เป็นพื้นที่ที่อยู่เสมือนซึ่งถูกแมปใน RAM แต่ RES คือจำนวน RAM จริงที่ใช้โดยกระบวนการ - เพียง 3.7 kB และจากนั้นบางส่วนเป็นส่วนหนึ่งของอาณาเขตที่ใช้ร่วมกันที่กล่าวถึงข้างต้น - 1.8 kB SHR แต่/bin/bashบนดิสก์ของฉันคือ 930 kB และ libc พื้นฐานมันเชื่อมโยงไปยัง (แชร์ lib) สองครั้งใหญ่อีกครั้ง

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

นี้เรียกว่าความต้องการของเพจ


9

ในขณะที่กำลังรอหนึ่งในรุ่นใหญ่ที่จะมาถึงและให้มุมมองทางประวัติศาสตร์เต็มรูปแบบฉันจะให้ความเข้าใจที่ จำกัด มากขึ้น

Built-in คำสั่งเช่นalias, cd, echoฯลฯ เป็นส่วนหนึ่งของเปลือกของคุณ ( bash, zsh, kshหรืออะไรก็ตาม) พวกมันถูกโหลดในเวลาเดียวกันที่เชลล์เป็นและเป็นเพียงฟังก์ชันภายในของเชลล์นั้น


4

ฉันได้ทดลองต่อไปนี้เพื่อแสดงให้เห็นว่าคำสั่งในตัวที่มีการโหลดในความเป็นจริงเป็นส่วนหนึ่งของ bashexectuable ดังนั้นทำไมพวกเขาถึงเรียกว่า builtins แต่การสาธิตเป็นวิธีที่ดีที่สุดในการพิสูจน์บางสิ่งบางอย่างเสมอ

ตัวอย่าง

  1. เริ่มbashเชลล์ใหม่และจดบันทึก ID กระบวนการ (PID):

    $ bash
    $ echo $$
    6402
    
  2. ในเทอร์มินัลที่สองรันpsคำสั่งเพื่อให้เราสามารถดูและดูว่าbashเริ่มใช้หน่วยความจำเพิ่มเติมใด ๆ :

    $ watch "ps -Fp 6402"
    

    ผลลัพธ์มีลักษณะดังนี้:

    Every 2.0s: ps -Fp 6402                        Sat Sep 14 14:40:49 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml      6402  6349  0 28747  6380   1 14:33 pts/38   00:00:00 bash
    

    หมายเหตุ:การใช้หน่วยความจำจะแสดงพร้อมคอลัมน์ SZ & RSS ที่นี่

  3. เริ่มเรียกใช้คำสั่งในเชลล์ (pid 6402):

    ในขณะที่คุณcdอยู่รอบ ๆ คุณจะสังเกตเห็นว่าหน่วยความจำมีความจริงเพิ่มขึ้น แต่นี่ไม่ได้เป็นเพราะการปฏิบัติการที่cdถูกโหลดเข้าสู่หน่วยความจำ แต่นี่เป็นเพราะโครงสร้างไดเรกทอรีบนดิสก์กำลังโหลดเข้าสู่หน่วยความจำ หากคุณยังคงcdอยู่ในไดเรกทอรีอื่น ๆ คุณจะเห็นมันเพิ่มขึ้นเรื่อย ๆ

    Every 2.0s: ps -Fp 30208                        Sat Sep 14 15:11:22 2013
    
    UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
    saml     30208  6349  0 28780  6492   0 15:09 pts/38   00:00:00 bash
    

    คุณสามารถทำการทดสอบที่ซับซ้อนมากขึ้นเช่นนี้:

    $ for i in `seq 1000`; do cd ..; cd 90609;done
    

    คำสั่งนี้จะเพิ่มระดับซีดีแล้วสำรองข้อมูลลงในไดเรกทอรี 90609 1,000 ครั้ง ในขณะที่เรียกใช้สิ่งนี้หากคุณตรวจสอบการใช้หน่วยความจำในpsหน้าต่างคุณจะสังเกตเห็นว่ามันไม่เปลี่ยนแปลง ในขณะที่ใช้งานสิ่งนี้ไม่ควรสังเกตการใช้งานหน่วยความจำเพิ่มเติม

  4. strace

    นี่คืออีกสิ่งหนึ่งที่บอกว่าเรากำลังเผชิญกับฟังก์ชั่นบิวอินในตัวbashแทนที่จะเป็นไฟล์ปฏิบัติการจริง เมื่อคุณลองและเรียกใช้strace cd ..คุณจะได้รับข้อความต่อไปนี้:

    $ strace cd ..
    strace: cd: command not found
    

3

"คำสั่งในตัว" หมายถึงคำสั่งในตัวเชลล์แทนที่จะเป็นโปรแกรมแยกต่างหาก lsตัวอย่างเช่นจริงๆแล้วไม่ใช่คำสั่งในตัว แต่เป็นโปรแกรมแยกต่างหาก มันจะถูกโหลดเข้าสู่ RAM เมื่อมีการเรียกใช้เว้นแต่จะมีอยู่ในดิสก์แคชแล้ว

ตัวอย่างของในตัวคำสั่งจะเป็นหรือprintf cdเหล่านี้เป็นส่วนหนึ่งของเปลือกและโหลดพร้อมกับส่วนที่เหลือของเปลือก

ไม่มีคำสั่งถูกโหลดล่วงหน้าตามค่าเริ่มต้นแม้ว่าระบบจะถูกสร้างขึ้นเพื่อทำสิ่งนี้

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