การนอนด้ายทำงานอย่างไร


15

เมื่อคุณนอนหลับสิ่งที่เกิดขึ้นจริงคืออะไร?

ผมเห็นว่าการนอนหลับหัวข้อ"หยุดเธรดปัจจุบันเป็นระยะเวลาที่กำหนดของเวลา" แต่มันทำงานอย่างไร

ตามที่Thread.sleep () ทำงานภายในและThread.sleep ทำงานอย่างไรจริง ๆ :

  • ระยะเวลาสลีปจะขึ้นอยู่กับความละเอียดเฉพาะของระบบ
  • การนอนหลับกำลังปิดกั้น
  • เธรดออกจาก CPU และหยุดการทำงาน
  • เธรดไม่ใช้เวลา CPU ในขณะหลับ

ฉันไม่เข้าใจกลไกภายในและพื้นฐานของความหมายทั้งหมดนี้

ฉันเข้าใจว่ามีบางสิ่งที่เรียกว่าตัวกำหนดตารางเวลาที่รับผิดชอบในการสลับระหว่างเธรด

ดูเหมือนแหล่งที่มาจะบ่งบอกว่าสิ่งนี้จะแตกต่างกันไปตามระบบปฏิบัติการ (หรือฮาร์ดแวร์?) และเธรดส่วนใหญ่จะได้รับ 1ms - 60ms หรือมากกว่านั้นเพื่อดำเนินการบางอย่างก่อนที่ CPU จะเปลี่ยนไปใช้เธรดอื่น

แต่เมื่อเธรดหลับ (เช่นหลายวินาที) มันจะทำงานต่อได้อย่างไร? ฉันคาดเดาว่าตัวจับเวลามีส่วนเกี่ยวข้องอย่างใดอย่างหนึ่งมันเป็นนาฬิกาของเมนบอร์ดหรือไม่ มันเกี่ยวข้องกับอัตราสัญญาณนาฬิกาของ CPU หรือไม่

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

กำลังนอนหลับภาษาเฉพาะของเธรดหรือระบบปฏิบัติการรับผิดชอบหรือไม่หรือเป็นสิ่งที่จำเพาะกับ CPU

ใครช่วยอธิบายสิ่งนี้ให้ฉันด้วยคำอธิบายพื้นฐานของสิ่งต่าง ๆ เช่นตัวกำหนดตารางเวลาและซีพียูกำลังทำอะไรอยู่ในระหว่างนี้?


2
การปลุกชุดนอนหลับทำงานอีกครั้งโดยการขัดจังหวะตามกำหนดเวลาซึ่งโดยทั่วไปจะสร้างโดยนาฬิกาขัดจังหวะซึ่งเป็นส่วนประกอบฮาร์ดแวร์ที่แยกจากส่วนหลักของ CPU ซึ่งประมวลผลคำแนะนำ ที่หลีกเลี่ยงความต้องการในการสำรวจ บางทีคำอธิบายเกี่ยวกับ Quora นี้จะอธิบายบางอย่าง: quora.com/How-does-threading-work-at-CPU-level
Doc Brown

1
JVM ส่วนใหญ่ไม่ได้ใช้มัลติเธรดจริง: ทั้งหมดที่พวกเขาทำคือการใช้ความสามารถในการมัลติเธรดของระบบปฏิบัติการพื้นฐาน หากคุณต้องการทราบวิธีการทำงานจริง ๆ มีหนังสือมากมายเกี่ยวกับการออกแบบระบบปฏิบัติการ
โซโลมอนช้า

คำตอบ:


11

มีส่วนร่วมในการใช้งานโปรแกรมมากกว่ารหัสในโปรแกรมนั้น

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

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


นี่คือ (โดยทั่วไป) จริงของกระบวนการ แต่ไม่จริงเสมอของเธรดซึ่งบางครั้งก็ขึ้นอยู่กับภาษา หัวข้อสามารถดำเนินการได้อย่างอิสระจากระบบปฏิบัติการและสามารถร่วมมือหรือครอบครอง ตัวอย่างเช่น Ruby มี "เส้นใย" (นอกเหนือจากเธรด) เส้นใยทับทิมมีการจัดตารางเวลาร่วมกัน
david25272

เป็นจริงมีเธรดดั้งเดิมเท่านั้นที่ทำงานเช่นนี้ เธรดสีเขียวถูกกำหนดเวลาไว้โดย VM ดำเนินการโปรแกรมในภาษาที่คอมไพล์ด้วยไบต์ โดยทั่วไปจะใช้เมื่อเธรดดั้งเดิมไม่พร้อมใช้งานหรือเมื่อเรียกใช้รหัสที่ไม่เหมาะสมกับเธรดที่ปลอดภัย (ในบางครั้ง VM สามารถตรวจสอบให้แน่ใจว่าซีแมนทิกส์ของโปรแกรมแบบมัลติเธรดยังคงถูกต้องด้วยวิธีการที่
Kilian Foth

7

ดังที่Doc Brownกล่าวถึงในความคิดเห็นการขัดจังหวะเป็นสิ่งสำคัญไม่ใช่เพื่อการนอนหลับ

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

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

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

ดังนั้นเมื่อคุณรันสลีปเธรดสิ่งที่คุณกำลังทำคือบอกระบบปฏิบัติการว่า (1) คุณสละเวลาให้กับคุณและ (2) คุณไม่ควรตื่นขึ้นมาอีกจนกว่าจะถึงเวลาที่กำหนด

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

สิ่งนี้ควรให้ความคิดแก่คุณว่าทำไมเวลานอนไม่แน่นอน: เมื่อเธรดของคุณพร้อมที่จะทำงานอาจมีเธรดอื่นที่ยังคงทำงานอยู่และยังไม่หมดเวลาใช้งาน หรืออาจมีเธรดที่มีลำดับความสำคัญสูงกว่าที่พร้อมจะรัน


นี่คือวิธีการทำงานของระบบปฏิบัติการ "ทันสมัย" ในระบบปฏิบัติการรุ่นเก่าเช่น Windows 3 หรือ Mac OS ก่อนหน้า OS X กระบวนการต้องให้การควบคุม () กับระบบปฏิบัติการ น่าเสียดายถ้าโปรแกรมค้างในลูปหรือหยุดชะงักอย่างใดโปรแกรมอาจไม่ยอมให้การควบคุมและทั้งระบบจะหยุดทำงาน
david25272

@ david25272 - ฉันคิดว่าฉันจะใช้คำว่า "เรียบง่าย" มากกว่า "เก่ากว่า" เนื่องจากมีระบบจากทศวรรษที่ 1960 ที่ใช้มัลติทาสก์แบบยึดเอาเสียก่อน และในขณะที่มันเป็นความจริงที่การทำงานมัลติทาสก์แบบร่วมมือต้องใช้เธรดที่ใช้งานเพื่อทำบางสิ่งบางอย่างเพื่อปล่อยการควบคุมโปรเซสเซอร์ (โดยทั่วไปแล้วโดยการเรียกการบล็อกระบบแทนที่จะให้ผลที่ชัดเจน) ฉันไม่เชื่อว่ามีโปรแกรมเมอร์ทั่วไปจำนวนมาก วันนี้ผู้ใช้ระบบปฏิบัติการที่มีรูปแบบเธรดที่ทำงานร่วมกัน
kdgregory
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.