เธรดบนโปรเซสเซอร์หมายถึงอะไร? สั้น ๆ ตรงประเด็นและพื้นหลังเล็กน้อย

กระบวนการ(หรืองาน) เป็นนามธรรมที่อธิบายโปรแกรมที่กำลังรันอยู่

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

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

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

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

ปัจจุบันระบบปฏิบัติการส่วนใหญ่กำหนดหน่วยงานไว้ 2 ประเภท หน่วยงานที่ใหญ่กว่า ปกติเรียกว่ากระบวนการหรืองาน จำเป็นต้องมีงานเล็กๆ หลายชิ้นจึงจะเสร็จสมบูรณ์ ซึ่งเรียกว่าเธรดหรือเธรด

แน่นอนว่าการดำเนินการใด ๆ ของระบบคอมพิวเตอร์ประกอบด้วยการรันโปรแกรมบางโปรแกรม ดังนั้นรหัสโปรแกรมบางตัวจึงเชื่อมโยงกับทั้งกระบวนการและเธรดซึ่งเพื่อวัตถุประสงค์เหล่านี้ได้รับการออกแบบในรูปแบบของโมดูลที่ปฏิบัติการได้ ในการที่จะรันโค้ดโปรแกรมนี้ จะต้องโหลดมันลงใน RAM ซึ่งบางทีอาจเป็นพื้นที่ดิสก์บางส่วนที่จัดสรรไว้สำหรับการจัดเก็บข้อมูล การเข้าถึงอุปกรณ์อินพุต/เอาท์พุต เช่น พอร์ตอนุกรม- ในระหว่างการดำเนินการ โปรแกรมอาจจำเป็นต้องเข้าถึง HI เช่น ไฟล์ต่างๆ และแน่นอนว่าเป็นไปไม่ได้ที่จะรันโปรแกรมโดยไม่ต้องจัดเตรียมไว้ให้ เวลาซีพียู, เช่น. เวลาที่โปรเซสเซอร์รันโค้ดของโปรแกรมที่กำหนด

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

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

มีสถานะพื้นฐานสามสถานะสำหรับกระบวนการ: พร้อมใช้งาน กำลังทำงาน และถูกบล็อก

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

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

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

ประมวลผลพื้นที่ที่อยู่เสมือนคือชุดของที่อยู่ที่สามารถจัดการได้โดยโมดูลโปรแกรมกระบวนการ

ระบบปฏิบัติการแมปพื้นที่ที่อยู่เสมือนของกระบวนการกับหน่วยความจำฟิสิคัลที่จัดสรรของกระบวนการ

เมื่อจำเป็นต้องมีการโต้ตอบ กระบวนการต่างๆ จะหันไปหาระบบปฏิบัติการ ซึ่งทำหน้าที่เป็นตัวกลาง จัดเตรียมวิธีการสื่อสารระหว่างกระบวนการ - ไปป์ไลน์ กล่องจดหมาย, ส่วนหน่วยความจำที่ใช้ร่วมกัน และอื่นๆ บางส่วน

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

เธรดเกิดขึ้นใน OS เป็นวิธีการคำนวณแบบขนาน แน่นอนว่าปัญหาการคำนวณแบบขนานภายในแอปพลิเคชันเดียวสามารถแก้ไขได้โดยใช้วิธีการแบบดั้งเดิม

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

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

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

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

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

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

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

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

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

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

ตัวอย่างของตัวอธิบายกระบวนการคือ Task Control Block (TCB) ใน OS/360, Process Control Block (PCB) ใน OS/2, ตัวจัดการกระบวนการใน UNIX, object-process ใน Windows NT

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

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

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

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

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

การวางแผนกระบวนการรวมถึงการแก้ไขงานต่อไปนี้:

■ การกำหนดช่วงเวลาในการเปลี่ยนแปลงกระบวนการที่กำลังดำเนินการ

■ การเลือกกระบวนการที่จะดำเนินการจากคิวของกระบวนการที่พร้อม;

■ สลับบริบทของกระบวนการ "เก่า" และ "ใหม่"

ปัญหาสองข้อแรกได้รับการแก้ไขแล้ว ซอฟต์แวร์และอย่างหลังนั้นใช้ฮาร์ดแวร์เป็นส่วนใหญ่

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

ตาม อัลกอริธึมตามการหาปริมาณการเปลี่ยนแปลงกระบวนการที่ใช้งานอยู่จะเกิดขึ้นหาก:

■ กระบวนการสิ้นสุดและออกจากระบบ

■ มีข้อผิดพลาดเกิดขึ้น;

■ กระบวนการได้เข้าสู่สถานะ "รอ";

■ ส่วนแบ่งเวลาของโปรเซสเซอร์ที่จัดสรรให้กับกระบวนการนี้หมดลงแล้ว

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

ควอนตัมที่จัดสรรให้กับกระบวนการสามารถเหมือนกันสำหรับกระบวนการทั้งหมดหรือต่างกันก็ได้ ควอนตัมที่จัดสรรให้กับกระบวนการหนึ่งอาจมีค่าคงที่หรือเปลี่ยนแปลงไปตามช่วงอายุของกระบวนการที่ต่างกัน กระบวนการที่ไม่ได้ใช้ควอนตัมที่จัดสรรให้กับกระบวนการอย่างเต็มที่ (เช่น เนื่องจากกิจกรรม I/O) อาจหรืออาจไม่ได้รับการชดเชยในรูปแบบของสิทธิพิเศษในระหว่างการบำรุงรักษาในภายหลัง คิวของกระบวนการที่พร้อมสามารถจัดระเบียบได้หลายวิธี: เป็นแบบวนตามกฎ "เข้าก่อนออกก่อน" (FIFO) หรือตามกฎ "เข้าหลังออกก่อน" (LIFO)

ใน อัลกอริธึมตามลำดับความสำคัญใช้แนวคิดเรื่อง "ลำดับความสำคัญ" ของกระบวนการ

ลำดับความสำคัญ– นี่คือตัวเลขที่แสดงถึงระดับสิทธิพิเศษของกระบวนการเมื่อใช้ทรัพยากร คอมพิวเตอร์โดยเฉพาะเวลา CPU ยิ่งลำดับความสำคัญสูง สิทธิ์ก็จะยิ่งสูงขึ้น

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

อัลกอริธึมลำดับความสำคัญมีสองประเภท: อัลกอริธึมที่ใช้ลำดับความสำคัญแบบสัมพันธ์และอัลกอริธึมที่ใช้ลำดับความสำคัญแบบสัมบูรณ์

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

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

กระบวนงานการจัดกำหนดการกระบวนการมีสองประเภทหลัก: แบบยึดเอาเสียก่อนและแบบไม่ยึดเอาเสียก่อน

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

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

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

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

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

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

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

อย่างไรก็ตาม ระบบปฏิบัติการสมัยใหม่เกือบทั้งหมดมุ่งเน้นไปที่การดำเนินการแอปพลิเคชันประสิทธิภาพสูง (UNIX, Windows NT, OS/2, VAX/VMS) ใช้งานมัลติทาสก์แบบยึดถือล่วงหน้า ล่าสุด ระบบปฏิบัติการระดับเดสก์ท็อปได้มาถึงแล้ว บางทีด้วยเหตุผลนี้จึงมักเรียกการทำงานหลายอย่างพร้อมกันล่วงหน้า จริง.

7 คำตอบ

ขึ้นอยู่กับฮาร์ดแวร์ เนื่องจากคุณ (อาจ) ไม่ได้ใช้งาน คอมพิวเตอร์เชิงทฤษฎีแต่เป็นฮาร์ดแวร์ทางกายภาพ ดังนั้นคุณจึงมีทรัพยากรที่จำกัด

นอกจากนี้ แม้ว่าคุณอาจใช้งานมากกว่า 5,000 เธรด ขึ้นอยู่กับฮาร์ดแวร์ของคุณ แต่นั่นอาจช้ากว่าโปรแกรมที่เทียบเท่า 10 เธรดมาก ฉันคิดว่าคุณควรดูการรวมเธรด

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

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

พูดตามตรง ฉันจะบอกว่าฉันทำมัลติเธรดเป็นจำนวนมากใน .NET/Windows เพราะคนๆ หนึ่งมักจะทำ "ความเสียหาย" มากกว่าผลดีเมื่อคุณไม่มีความเข้าใจที่แท้จริง NET มีแนวคิดเกี่ยวกับกลุ่มเธรดและคุณจำเป็นต้องทำ รู้วิธีการทำงานนอกเหนือจาก Windows

ใน .NET 3.5/4.0 คุณควรดูที่ Task Parallel Library เนื่องจากไลบรารีจะดีกว่ามากในการกำหนดจำนวนเธรด (ถ้ามี) ที่จะวางไข่ ด้วย TPL เธรดพูลได้รับการยกเครื่องครั้งใหญ่และชาญฉลาดกว่ามากเกี่ยวกับการคูณเธรดและการขโมยงาน ฯลฯ แต่โดยปกติแล้วคุณทำงานกับงาน ไม่ใช่เธรด

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

แต่ละเธรดใช้หน่วยความจำมากขึ้น (เคอร์เนลสแต็ก, บล็อกสภาพแวดล้อมของเธรด, เธรดภายใน, สแต็ก....) AFAIK ไม่มีข้อจำกัดที่ชัดเจนบน Windows ดังนั้นขีดจำกัดจะเป็นหน่วยความจำ (อาจเป็นสแต็กต่อเธรด)

ใน เธรดลินุกซ์กระบวนการที่คล้ายกันมากขึ้น (หน่วยความจำที่ใช้ร่วมกัน) และคุณถูกจำกัดไว้ที่:

Cat /proc/sys/kernel/threads-max

กฎง่ายๆ ที่ดีเมื่อต้องทำงานที่เข้มข้นคือการรันตัวเลขเดียวกันกับจำนวนคอร์ทางกายภาพของคุณ

ใช่ คุณสามารถรันงานได้มากขึ้น แต่งานเหล่านั้นจะรอทรัพยากร (หรือเธรดในกลุ่มเธรด) และกล่องของคุณ ไม่ว่าจะมีขนาดเท่าใดก็ตาม จะไม่สามารถจัดสรรทรัพยากร CPU หลักทั้งหมดให้กับเธรดได้ 100% เนื่องจากพื้นหลัง/ กระบวนการอื่นๆ ดังนั้น ยิ่งคุณสร้างงานมากเท่าไร คุณก็ยิ่งสร้างเธรดมากขึ้นเท่านั้น เนื่องจากงานเหล่านั้นมีจำนวนมากกว่าเธรดแบบขนานที่เป็นไปได้จริง (1 ต่อคอร์) ยิ่งมีการจัดการทรัพยากร การเข้าคิว และการสลับมากขึ้นเท่านั้น

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

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

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

เพื่อกำหนดสิ่งนี้โดยทางโปรแกรมเราใช้

var CoreCount = System.Environment.ProcessorCount / 2;

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

ฉันสามารถรัน 4 เธรดพร้อมกันบนโปรเซสเซอร์เก่าปัจจุบันของฉัน (2005) การใช้ตัวเขียน CPU EVGA ก่อนที่เสียงสัญญาณ CPU ของฉันจะดังขึ้น (ตั้งโปรแกรมไว้ในเมนู BIOS) ค่า i เกิน 90 * c โปรดทราบว่าเรากำลังพูดถึงสตรีมข้อมูลที่ทำงานพร้อมกัน ตัวอย่างที่ดีก็คือการเปิดหลายโปรแกรมพร้อมกัน แต่โดยรวมแล้วขึ้นอยู่กับว่าโปรเซสเซอร์ของคุณทำงานหลายอย่างพร้อมกันได้ดีแค่ไหน (กล่าวอีกนัยหนึ่ง สามารถประมวลผลเธรดที่ใช้งานอยู่จำนวนมากได้) ด้วยวิธีที่ปลอดภัยการทดสอบคือการโหลด "ocscanner (By EVGA)" และ "CPU Temperature" โดยใช้ CPU ลงใน OC Scanner ขณะทดสอบ ตรวจสอบให้แน่ใจว่าอุณหภูมิของคุณไม่สูงกว่า 90*c (หรืออุณหภูมิใดก็ตามที่คุณรู้สึกปลอดภัย) และดูจำนวนเธรดปัจจุบันที่คุณใช้งาน CPU ของคุณ เริ่มต้นด้วย 2 เธรด รอ 3-5 นาที สังเกตอุณหภูมิของ CPU เพิ่มอีกเธรด ทำซ้ำ (อย่ายอมรับโชคของคุณ!!!) (อย่าลองถ้าเทอร์โมมิเตอร์ของ CPU ไม่สามารถรับอุณหภูมิของคุณได้!!!)

  • บทช่วยสอน

ในบทความนี้ ฉันจะพยายามอธิบายคำศัพท์ที่ใช้อธิบายระบบที่สามารถรันหลายโปรแกรมพร้อมกันได้ นั่นคือ multi-core, multi-processor, multi-threaded ประเภทต่างๆความขนานใน CPU IA-32 ปรากฏขึ้น เวลาที่แตกต่างกันและอยู่ในลำดับที่ค่อนข้างไม่สอดคล้องกัน ทั้งหมดนี้ค่อนข้างง่ายที่จะสับสน โดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่าระบบปฏิบัติการซ่อนรายละเอียดอย่างระมัดระวังจากโปรแกรมแอปพลิเคชันที่ซับซ้อนน้อยกว่า

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

คำเตือนเกี่ยวกับสัญญาณ ®, ™ ในบทความ

ความคิดเห็นของฉันอธิบายว่าทำไมพนักงานของบริษัทจึงควรใช้ประกาศเกี่ยวกับลิขสิทธิ์ในการสื่อสารสาธารณะ ในบทความนี้ฉันต้องใช้มันค่อนข้างบ่อย

ซีพียู

แน่นอนว่าคำที่เก่าที่สุด ใช้บ่อยที่สุด และเป็นที่ถกเถียงกันคือ "โปรเซสเซอร์"

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

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

การสนับสนุนหลายอย่าง หน่วยประมวลผลกลางในระบบหนึ่งต้องมีการเปลี่ยนแปลงการออกแบบมากมาย อย่างน้อยที่สุด จำเป็นต้องตรวจสอบให้แน่ใจว่ามีการเชื่อมต่อทางกายภาพ (มีซ็อกเก็ตหลายช่องบนเมนบอร์ด) แก้ไขปัญหาการระบุตัวโปรเซสเซอร์ (ดูภายหลังในบทความนี้ เช่นเดียวกับบันทึกย่อก่อนหน้าของฉัน) การประสานงานของการเข้าถึงหน่วยความจำและการขัดจังหวะการจัดส่ง ( ตัวควบคุมการขัดจังหวะจะต้องสามารถกำหนดเส้นทางการขัดจังหวะสำหรับโปรเซสเซอร์หลายตัว) และแน่นอนว่าต้องได้รับการสนับสนุนจากระบบปฏิบัติการ น่าเสียดายที่ฉันไม่พบสารคดีที่กล่าวถึงการสร้างระบบมัลติโปรเซสเซอร์ตัวแรกบนโปรเซสเซอร์ Intel แต่ Wikipedia อ้างว่า Sequent Computer Systems จัดหามาให้แล้วในปี 1987 โดยใช้โปรเซสเซอร์ Intel 80386 การรองรับชิปหลายตัวในระบบเดียวกำลังแพร่หลาย , เริ่มต้นด้วย Intel® Pentium

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


พร้อมบินขึ้น! บอร์ดเดสก์ท็อป Intel® D5400XS

แกนกลาง

ในอดีต มัลติคอร์ใน Intel IA-32 ปรากฏช้ากว่า Intel® HyperThreading แต่ในลำดับชั้นเชิงตรรกะจะปรากฏเป็นลำดับถัดไป

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

โปรเซสเซอร์ IA-32 แบบมัลติคอร์ตัวแรกจาก Intel เปิดตัวในปี 2548 ตั้งแต่นั้นเป็นต้นมา จำนวนคอร์เฉลี่ยในเซิร์ฟเวอร์ เดสก์ท็อป และตอนนี้ แพลตฟอร์มมือถือกำลังเติบโตอย่างต่อเนื่อง

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


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

ไฮเปอร์เธรด

จนถึงประมาณปี 2002 วิธีเดียวที่จะได้รับระบบ IA-32 ที่สามารถรันโปรแกรมสองโปรแกรมขึ้นไปพร้อมกันได้คือการใช้ระบบมัลติโปรเซสเซอร์ เปิดตัว Intel® Pentium® 4 และกลุ่มผลิตภัณฑ์ Xeon ที่มีชื่อรหัสว่า Foster (Netburst) เทคโนโลยีใหม่- ไฮเปอร์เธรดหรือไฮเปอร์เธรด - Intel® HyperThreading (ต่อไปนี้จะเรียกว่า HT)

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

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

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

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

มีการสังเกตสถานการณ์ที่แตกต่างกันในงานทั่วไปที่ทำกับตัวเร่งความเร็ววิดีโอ ดังนั้นสถาปัตยกรรมเหล่านี้จึงโดดเด่นด้วยการใช้เทคโนโลยี SMT ที่มีเธรดจำนวนมากขึ้น เนื่องจากโปรเซสเซอร์ร่วม Intel® Xeon Phi (เปิดตัวในปี 2010) ค่อนข้างใกล้เคียงกับการ์ดวิดีโอทั้งในด้านอุดมการณ์และลำดับวงศ์ตระกูล จึงอาจมี สี่ไฮเปอร์เธรดในแต่ละคอร์ - การกำหนดค่าเฉพาะสำหรับ IA-32

โปรเซสเซอร์แบบลอจิคัล

จากสาม “ระดับ” ของการขนานที่อธิบายไว้ (โปรเซสเซอร์, คอร์, ไฮเปอร์เธรด) บางส่วนหรือทั้งหมดอาจหายไปในระบบใดระบบหนึ่ง สิ่งนี้ได้รับอิทธิพล การตั้งค่าไบออส(มัลติคอร์และมัลติเธรดถูกปิดใช้งานโดยแยกจากกัน) คุณสมบัติสถาปัตยกรรมไมโคร (เช่น HT หายไปจาก Intel® Core™ Duo แต่ถูกส่งคืนพร้อมกับการเปิดตัว Nehalem) และเหตุการณ์ของระบบ (เซิร์ฟเวอร์มัลติโปรเซสเซอร์สามารถปิดได้ โปรเซสเซอร์ที่ล้มเหลวหากตรวจพบข้อผิดพลาดและยังคง "บิน" ต่อไปกับตัวประมวลผลที่เหลือ) สวนสัตว์แห่งการทำงานพร้อมกันหลายระดับนี้มองเห็นได้สำหรับระบบปฏิบัติการและท้ายที่สุดกับแอปพลิเคชันแอปพลิเคชันอย่างไร

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

บ่อยครั้งที่ระบบปฏิบัติการซ่อนคุณลักษณะของโทโพโลยีทางกายภาพของระบบที่ใช้งานอยู่จากแอปพลิเคชันปลายทาง ตัวอย่างเช่น โทโพโลยีสามรายการต่อไปนี้: (2, 1, 1), (1, 2, 1) และ (1, 1, 2) - ระบบปฏิบัติการจะแสดงเป็นสอง โปรเซสเซอร์แบบลอจิคัลแม้ว่าตัวแรกจะมีโปรเซสเซอร์สองตัว แต่ตัวที่สองมีสองคอร์และตัวที่สามมีเพียงสองเธรดเท่านั้น


หน้าต่าง ผู้จัดการงานแสดงตัวประมวลผลแบบลอจิคัล 8 ตัว แต่ราคาเท่าไหร่ในโปรเซสเซอร์, คอร์และไฮเปอร์เธรด?


Linux อันดับต้น ๆ แสดงตัวประมวลผลแบบลอจิคัล 4 ตัว

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

คำจำกัดความของซอฟต์แวร์โทโพโลยี

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

ข้อมูลเกี่ยวกับโทโพโลยีของระบบโดยรวม รวมถึงตำแหน่งของตัวประมวลผลแบบลอจิคัลแต่ละตัวใน IA-32 มีให้ใช้งานโดยใช้คำสั่ง CPUID นับตั้งแต่การถือกำเนิดของระบบมัลติโปรเซสเซอร์ระบบแรก รูปแบบการระบุตัวประมวลผลแบบลอจิคัลได้ถูกขยายออกไปหลายครั้ง จนถึงปัจจุบัน ชิ้นส่วนต่างๆ มีอยู่ในเอกสาร CPUID แผ่นที่ 1, 4 และ 11 แผ่นงานใดที่จะดูสามารถกำหนดได้จากผังงานต่อไปนี้ที่นำมาจากบทความ:

ฉันจะไม่ทำให้คุณเบื่อที่นี่พร้อมรายละเอียดทั้งหมดของแต่ละส่วนของอัลกอริทึมนี้ หากมีความสนใจสามารถอุทิศส่วนถัดไปของบทความนี้ได้ ฉันจะแนะนำผู้อ่านที่สนใจซึ่งจะตรวจสอบปัญหานี้อย่างละเอียดที่สุดเท่าที่จะเป็นไปได้ ในที่นี้ฉันจะอธิบายสั้น ๆ ก่อนว่า APIC คืออะไร และเกี่ยวข้องกับโทโพโลยีอย่างไร ต่อไปเราจะมาดูการทำงานกับชีต 0xB (สิบเอ็ดนิ้ว) ทศนิยม) ซึ่งเปิดอยู่ ตอนนี้เป็นคำสุดท้ายใน “apico-building”

รหัส APIC
Local APIC (ตัวควบคุมการขัดจังหวะแบบตั้งโปรแกรมได้ขั้นสูง) เป็นอุปกรณ์ (ปัจจุบันเป็นส่วนหนึ่งของโปรเซสเซอร์) ที่รับผิดชอบในการจัดการการขัดจังหวะที่มาถึงตัวประมวลผลแบบลอจิคัลเฉพาะ ตัวประมวลผลแบบลอจิคัลแต่ละตัวมี APIC ของตัวเอง และแต่ละรายการในระบบจะต้องมีค่า APIC ID ที่ไม่ซ้ำกัน หมายเลขนี้ถูกใช้โดยตัวควบคุมการขัดจังหวะเพื่อระบุที่อยู่เมื่อส่งข้อความ และโดยคนอื่นๆ (เช่น ระบบปฏิบัติการ) เพื่อระบุตัวประมวลผลแบบลอจิคัล ข้อมูลจำเพาะสำหรับตัวควบคุมขัดจังหวะนี้ได้พัฒนาจาก Intel 8259 PIC ผ่าน Dual PIC, APIC และ xAPIC เป็น x2APIC

ปัจจุบันความกว้างของตัวเลขที่เก็บไว้ใน APIC ID มีจำนวนถึง 32 บิตเต็มแล้ว แม้ว่าในอดีตจะถูกจำกัดไว้ที่ 16 บิต และก่อนหน้านี้มีเพียง 8 บิตเท่านั้น ปัจจุบัน เศษของวันเก่าๆ กระจัดกระจายไปทั่ว CPUID แต่ CPUID.0xB.EDX ส่งคืน APIC ID ทั้ง 32 บิต ในตัวประมวลผลแบบลอจิคัลแต่ละตัวที่ดำเนินการคำสั่ง CPUID อย่างอิสระ ค่าที่แตกต่างกันจะถูกส่งกลับ

ค้นหาความสัมพันธ์ในครอบครัว
ค่า APIC ID ไม่ได้บอกอะไรคุณเกี่ยวกับโทโพโลยี หากต้องการทราบว่าตัวประมวลผลแบบลอจิคัลตัวใดสองตัวที่อยู่ในตัวประมวลผลจริงตัวเดียว (กล่าวคือ เป็นตัวประมวลผลแบบ "พี่น้อง" ) ตัวไหนสองตัวอยู่ภายในตัวประมวลผลเดียวกัน และตัวใดเป็นตัวประมวลผลที่แตกต่างกันโดยสิ้นเชิง คุณจะต้องเปรียบเทียบค่า APIC ID ของตัวประมวลผลเหล่านั้น บิตบางส่วนจะตรงกันทั้งนี้ขึ้นอยู่กับระดับของความสัมพันธ์ ข้อมูลนี้มีอยู่ในรายการย่อย CPUID.0xB ซึ่งมีการเข้ารหัสตัวถูกดำเนินการใน ECX แต่ละคนอธิบายตำแหน่งของฟิลด์บิตของหนึ่งในระดับโทโพโลยีใน EAX (แม่นยำยิ่งขึ้นคือจำนวนบิตที่ต้องเลื่อนไปทางขวาใน APIC ID เพื่อลบ ระดับล่างโทโพโลยี) เช่นเดียวกับประเภทของเลเยอร์นี้ - ไฮเปอร์เธรด, คอร์หรือโปรเซสเซอร์ - ใน ECX

ตัวประมวลผลแบบลอจิคัลที่อยู่ภายในคอร์เดียวกันจะมีบิต APIC ID ทั้งหมดเหมือนกัน ยกเว้นบิตที่อยู่ในฟิลด์ SMT สำหรับตัวประมวลผลแบบลอจิคัลที่อยู่ในตัวประมวลผลเดียวกัน บิตทั้งหมดยกเว้นฟิลด์ Core และ SMT เนื่องจากจำนวนแผ่นย่อยสำหรับ CPUID.0xB อาจเพิ่มขึ้น โครงการนี้จะช่วยให้เราสามารถรองรับคำอธิบายของโทโพโลยีด้วยจำนวนระดับที่มากขึ้น หากจำเป็นเกิดขึ้นในอนาคต ยิ่งไปกว่านั้น ยังสามารถแนะนำระดับกลางระหว่างระดับที่มีอยู่ได้

ผลที่ตามมาที่สำคัญของการจัดระเบียบโครงการนี้คืออาจมี "ช่องโหว่" ในชุด APIC ID ทั้งหมดของตัวประมวลผลลอจิคัลทั้งหมดในระบบ เช่น พวกเขาจะไม่ไปตามลำดับ ตัวอย่างเช่น ในโปรเซสเซอร์แบบมัลติคอร์ที่ปิด HT รหัส APIC ทั้งหมดอาจกลายเป็นเลขคู่ เนื่องจากบิตที่มีนัยสำคัญน้อยที่สุดที่รับผิดชอบในการเข้ารหัสหมายเลขไฮเปอร์เธรดจะเป็นศูนย์เสมอ

ฉันทราบว่า CPUID.0xB ไม่ใช่แหล่งข้อมูลเดียวเกี่ยวกับโปรเซสเซอร์แบบลอจิคัลที่มีอยู่ในระบบปฏิบัติการ รายการโปรเซสเซอร์ทั้งหมดที่พร้อมใช้งาน พร้อมด้วยค่า APIC ID จะถูกเข้ารหัสในตาราง MADT ACPI

ระบบปฏิบัติการและโทโพโลยี

ระบบปฏิบัติการให้ข้อมูลเกี่ยวกับโทโพโลยีของตัวประมวลผลแบบลอจิคัลแก่แอปพลิเคชันที่ใช้อินเทอร์เฟซของตนเอง

ใน ข้อมูลลินุกซ์ข้อมูลทอโพโลยีมีอยู่ในไฟล์เทียม /proc/cpuinfo รวมถึงในเอาต์พุตของคำสั่ง dmidecode ในตัวอย่างด้านล่าง ฉันกรองเนื้อหาของ cpuinfo บนระบบ Quad-Core บางระบบที่ไม่มี HT เหลือเพียงรายการที่เกี่ยวข้องกับโทโพโลยี:

ข้อความที่ซ่อนอยู่

ggg@shadowbox:~$ cat /proc/cpuinfo |grep "processor\|physical\ id\|siblings\|core\|cores\|apicid" โปรเซสเซอร์: 0 ฟิสิคัล id: 0 พี่น้อง: 4 คอร์ id: 0 คอร์ซีพียู: 2 apicid: 0 apicid เริ่มต้น: 0 ตัวประมวลผล: 1 ฟิสิคัล id: 0 พี่น้อง: 4 คอร์ id: 0 แกน cpu: 2 apicid: 1 apicid เริ่มต้น: 1 ตัวประมวลผล: 2 ฟิสิคัล id: 0 พี่น้อง: 4 คอร์ id: 1 คอร์ซีพียู: 2 apicid: 2 apicid เริ่มต้น: 2 ตัวประมวลผล: 3 id ทางกายภาพ: 0 พี่น้อง: 4 core id: 1 cpu cores: 2 apicid: 3 apicid เริ่มต้น: 3

บน FreeBSD โทโพโลยีจะถูกรายงานผ่านกลไก sysctl ในตัวแปร kern.sched.topology_spec เป็น XML:

ข้อความที่ซ่อนอยู่

ผู้ใช้ @ โฮสต์: ~ $ sysctl kern.sched.topology_spec kern.sched.topology_spec: 0, 1, 2, 3, 4, 5, 6, 7 0, 1, 2, 3, 4, 5, 6, 7 0, 1 กลุ่มเธรดกลุ่มเอสเอ็มที 2, 3 กลุ่มเธรดกลุ่มเอสเอ็มที 4, 5 กลุ่มเธรดกลุ่มเอสเอ็มที 6, 7 กลุ่มเธรดกลุ่มเอสเอ็มที

ใน MS Windows 8 ข้อมูลโทโพโลยีสามารถดูได้ในตัวจัดการงาน

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

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

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

กระบวนการประกอบด้วยหนึ่งเธรดขึ้นไปที่รันโค้ดจริงในกระบวนการ (ในทางเทคนิค ไม่ใช่กระบวนการที่ทำงาน แต่เป็นเธรด) และแสดงในระบบเป็นอ็อบเจ็กต์เธรดเคอร์เนล มีสาเหตุหลายประการที่แอปพลิเคชันสร้างเธรดเพิ่มเติมจากเธรดเริ่มต้นดั้งเดิม: 1) โดยทั่วไปกระบวนการที่มีอินเทอร์เฟซผู้ใช้จะสร้างเธรดเพื่อทำงานในขณะที่ยังคงรักษาเธรดหลักให้ตอบสนองต่อคำสั่งอินพุตของผู้ใช้และการจัดการหน้าต่าง 2) แอปพลิเคชันที่ต้องการใช้โปรเซสเซอร์หลายตัวเพื่อปรับขนาดประสิทธิภาพ หรือต้องการให้ทำงานต่อไปในขณะที่เธรดหยุดทำงานเพื่อรอให้ I/O ซิงโครไนซ์ สร้างเธรดเพื่อใช้ประโยชน์จากมัลติเธรด

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

โครงสร้าง Portable Executable (PE) ของอิมเมจที่ปฏิบัติการได้จะกำหนดจำนวนพื้นที่ที่อยู่ที่สงวนไว้และจัดสรรให้กับสแต็กของเธรดในขั้นต้น ตามค่าเริ่มต้นตัวเชื่อมโยงจะสงวน 1MB และจัดสรรหนึ่งหน้า (4KB) แต่นักพัฒนาสามารถเปลี่ยนค่าเหล่านี้ได้โดยการเปลี่ยนค่า PE เมื่อพวกเขาสื่อสารกับโปรแกรมของพวกเขาหรือโดยการเรียกใช้ฟังก์ชัน CreateTread บนเธรดแยกต่างหาก คุณสามารถใช้ยูทิลิตี้เช่น Dumpbin ซึ่งมาพร้อมกับ Visual Studio เพื่อดูการตั้งค่าของโปรแกรมที่ปฏิบัติการได้ นี่คือผลลัพธ์ของการรัน Dumpbin ด้วยตัวเลือก /headers บนไฟล์ปฏิบัติการที่สร้างโดยโครงการ Visual Studio ใหม่:

การแปลงตัวเลขจาก ระบบเลขฐานสิบหกแคลคูลัส คุณจะเห็นว่าขนาดการสำรองสแต็กคือ 1MB และพื้นที่หน่วยความจำที่จัดสรรคือ 4KB โดยใช้ ยูทิลิตี้ใหม่จาก Sysinternals ที่เรียกว่า MMap คุณสามารถแนบกับกระบวนการนี้และดูพื้นที่ที่อยู่ของกระบวนการได้ และดูหน้าหน่วยความจำสแต็กที่จัดสรรไว้แต่เดิมของกระบวนการ หน้าป้องกัน และส่วนที่เหลือของหน่วยความจำสแต็กที่สงวนไว้:

เนื่องจากแต่ละเธรดใช้ส่วนหนึ่งของพื้นที่ที่อยู่ของกระบวนการ กระบวนการจึงมีขีดจำกัดพื้นฐานเกี่ยวกับจำนวนเธรดที่สามารถสร้างได้ เท่ากับขนาดของพื้นที่ที่อยู่หารด้วยขนาดของสแต็กของเธรด

ข้อจำกัดของการสตรีมแบบ 32 บิต
แม้ว่ากระบวนการจะไม่มีรหัสหรือข้อมูลเลย และพื้นที่ที่อยู่ทั้งหมดสามารถใช้สำหรับสแต็กได้ แต่กระบวนการแบบ 32 บิตที่มีพื้นที่ที่อยู่เริ่มต้น 2 ไบต์สามารถสร้างเธรดได้สูงสุด 2,048 เธรด นี่คือผลลัพธ์ของ Testlimit ที่ทำงานบน Windows 32 บิตพร้อมตัวเลือก -t (การสร้างเธรด) เพื่อยืนยันการมีอยู่ของข้อจำกัดนี้:

อีกครั้ง เนื่องจากพื้นที่แอดเดรสบางส่วนถูกใช้ไปแล้วสำหรับโค้ดและหน่วยความจำฮีปเริ่มต้น จึงไม่มีพื้นที่ 2GB ทั้งหมดสำหรับสแต็กเธรด ดังนั้นจำนวนเธรดทั้งหมดที่สร้างขึ้นจึงไม่ถึงขีดจำกัดทางทฤษฎีที่ 2,048 เธรด

ฉันลองใช้ Testlimit ด้วย ตัวเลือกเพิ่มเติมซึ่งช่วยให้แอปพลิเคชันมีพื้นที่ที่อยู่เพิ่มเติม โดยหวังว่าหากได้รับพื้นที่ที่อยู่มากกว่า 2GB (เช่น บนระบบ 32 บิต สามารถทำได้โดยการเรียกใช้แอปพลิเคชันด้วยตัวเลือก /3GB หรือ /USERVA สำหรับ Boot ini หรือตัวเลือก BCD ที่เทียบเท่าบน Vista และใหม่กว่า เพิ่มผู้ใช้) มันจะใช้งาน กระบวนการ 32 บิตได้รับการจัดสรรพื้นที่ที่อยู่ 4GB เมื่อทำงานบน Windows 64 บิต ดังนั้น Testlimit 32 บิตที่ทำงานบน Windows 64 บิตสามารถสร้างได้กี่เธรด จากสิ่งที่เราได้พูดคุยไปแล้ว คำตอบควรเป็น 4096 (4GB หารด้วย 1MB) แต่ในทางปฏิบัติตัวเลขนี้จะน้อยกว่ามาก นี่คือ Testlimit 32 บิตที่ทำงานบน Windows XP 64 บิต:

สาเหตุของความแตกต่างนี้อยู่ที่ว่าเมื่อคุณเรียกใช้แอปพลิเคชัน 32 บิตบน Windows 64 บิต จริงๆ แล้วมันเป็นกระบวนการ 64 บิตที่รันโค้ด 64 บิตในนามของเธรด 32 บิต และดังนั้นจึงมีต่อ - พื้นที่หน่วยความจำเธรดถูกสงวนไว้สำหรับสแต็กเธรดแบบ 64 บิตและ 32 บิต สำหรับสแต็ก 64 บิต จะสงวนไว้ 256KB (ข้อยกเว้นคือ OS ที่เผยแพร่ก่อน Vista ซึ่งขนาดสแต็กเริ่มต้นของเธรด 64 บิตคือ 1MB) เนื่องจากเธรด 32 บิตทุกตัวเริ่มต้นในโหมด 64 บิต และขนาดสแต็กที่ได้รับการจัดสรรเมื่อเริ่มต้นระบบมีขนาดใหญ่กว่าขนาดหน้า ในกรณีส่วนใหญ่ คุณจะเห็นว่าสแต็กของเธรด 64 บิตได้รับการจัดสรรอย่างน้อย 16Kb นี่คือตัวอย่างของสแต็ก 64 บิตและ 32 บิตของสตรีม 32 บิต (สแต็ก 32 บิตมีป้ายกำกับว่า "Wow64"):

Testlimit 32 บิตสามารถสร้างเธรด 3204 บน Windows 64 บิต ซึ่งอธิบายได้จากข้อเท็จจริงที่ว่าแต่ละเธรดใช้พื้นที่ที่อยู่ 1MB + 256KB สำหรับสแต็ก (อีกครั้ง ข้อยกเว้นคือ เวอร์ชันของ Windowsไปยัง Vista โดยที่ใช้ 1MB+ 1MB) อย่างไรก็ตาม ฉันได้ผลลัพธ์ที่แตกต่างออกไปเมื่อใช้งาน Testlimit แบบ 32 บิตบน Windows 7 แบบ 64 บิต:

ความแตกต่างระหว่างผลลัพธ์บน Windows XP และ Windows 7 เกิดจากการสุ่มมากขึ้นของรูปแบบการจัดสรรพื้นที่ที่อยู่ของ Windows Vista ซึ่งก็คือ การสุ่มเค้าโครงพื้นที่ที่อยู่ (ASLR) ซึ่งนำไปสู่การแตกแฟรกเมนต์บางส่วน สุ่มโหลด DLL, สแต็กเธรด และตำแหน่ง หน่วยความจำแบบไดนามิกช่วยปรับปรุงการป้องกันมัลแวร์ ดังที่คุณเห็นในภาพรวมของโปรแกรม VMMap ต่อไปนี้ ระบบทดสอบยังคงมีพื้นที่ที่อยู่ 357MB แต่บล็อกว่างที่ใหญ่ที่สุดคือ 128KB ซึ่งน้อยกว่า 1MB ที่จำเป็นสำหรับสแต็ก 32 บิต:

ดังที่ฉันได้กล่าวไว้ นักพัฒนาสามารถแทนที่ขนาดการสำรองสแต็กเริ่มต้นได้ หนึ่งใน เหตุผลที่เป็นไปได้ซึ่งอาจทำได้เพื่อหลีกเลี่ยงการสิ้นเปลืองพื้นที่ที่อยู่เมื่อทราบล่วงหน้าว่าสแต็กของเธรดจะใช้น้อยกว่าค่าเริ่มต้น 1MB เสมอ อิมเมจ Testlimit PE ใช้ขนาดสแต็กสำรอง 64KB ตามค่าเริ่มต้น และเมื่อคุณระบุตัวเลือก -n พร้อมกับตัวเลือก -t Testlimit จะสร้างเธรดที่มีขนาดสแต็ก 64KB นี่คือผลลัพธ์ของการเรียกใช้ยูทิลิตี้นี้บนระบบที่มี Windows XP 32 บิตและ RAM 256MB (ฉันรันการทดสอบนี้โดยเฉพาะ ระบบอ่อนแอเพื่อเน้นย้ำข้อจำกัดนี้):

ควรสังเกตที่นี่ว่ามีข้อผิดพลาดอื่นเกิดขึ้น ซึ่งหมายความว่าในสถานการณ์นี้สาเหตุไม่ใช่พื้นที่ที่อยู่ ที่จริงแล้ว สแต็กขนาด 64Kb ควรมีเธรดประมาณ 32,000 เธรด (2Gb/64Kb = 32,768) แล้วมีข้อจำกัดอะไรปรากฏบ้าง ในกรณีนี้- หากคุณดูผู้สมัครที่เป็นไปได้ รวมถึงหน่วยความจำและพูลที่จัดสรร พวกเขาไม่ได้ให้เบาะแสใด ๆ ในการค้นหาคำตอบสำหรับคำถามนี้ เนื่องจากค่าทั้งหมดเหล่านี้ต่ำกว่าขีดจำกัด:

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

หน่วยความจำภายในที่มีอยู่คือหน่วยความจำกายภาพที่ได้รับการจัดสรรสำหรับข้อมูลหรือรหัสที่ต้องอยู่ใน RAM ขนาดของพูล nonpaged และโปรแกรมควบคุม nonpaged จะถูกคำนวณอย่างอิสระ ตามที่เป็นอยู่ ตัวอย่างเช่น หน่วยความจำที่สงวนไว้ใน RAM สำหรับการดำเนินการ I/O แต่ละเธรดมีทั้งสแต็กโหมดผู้ใช้ ดังที่ฉันได้กล่าวไปแล้ว แต่เธรดเหล่านั้นก็มีสแต็กโหมดสิทธิพิเศษ (โหมดเคอร์เนล) ซึ่งใช้เมื่อเธรดทำงานในโหมดเคอร์เนล เช่น การดำเนินการเรียกของระบบ เมื่อเธรดทำงานอยู่ เคอร์เนลสแต็กจะถูกปักหมุดไว้ในหน่วยความจำ เพื่อให้เธรดสามารถรันโค้ดในเคอร์เนลซึ่งเพจที่จำเป็นอาจไม่หายไป

เคอร์เนลสแต็กหลักใช้พื้นที่ 12Kb บน Windows 32 บิต และ 24Kb บน Windows 64 บิต 14225 เธรดต้องการหน่วยความจำภายในประมาณ 170MB ซึ่งเป็นจำนวนหน่วยความจำว่างในระบบนี้อย่างแน่นอนโดยปิดใช้งาน Testlimit:

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

ตามที่คาดไว้ Testlimit ทำงานบน Windows 64 บิตพร้อม RAM 256MB สามารถสร้างเธรดได้ 6,600 เธรด - ประมาณครึ่งหนึ่งของจำนวนเธรดที่สามารถสร้างบน Windows 32 บิตพร้อม RAM 256MB ก่อนที่หน่วยความจำจะหมด:

เหตุผลที่ก่อนหน้านี้ฉันใช้คำว่าเคอร์เนลสแต็ก "ฐาน" คือเธรดที่ทำฟังก์ชันกราฟิกและหน้าต่างจะได้รับสแต็ก "ใหญ่" เมื่อทำการเรียกครั้งแรก ซึ่งเท่ากับ (หรือมากกว่า) 20Kb ต่อ 32 บิต Windows และ 48Kb บน Windows 64 บิต เธรด Testlimit จะไม่เรียก API ดังกล่าว ดังนั้นจึงมีเคอร์เนลสแต็กพื้นฐาน
ข้อจำกัดของการสตรีมแบบ 64 บิต

เช่นเดียวกับเธรด 32 บิต เธรด 64 บิตมีการสำรองสแต็ก 1MB ตามค่าเริ่มต้น แต่เธรด 64 บิตมีพื้นที่ที่อยู่ผู้ใช้มากกว่ามาก (8TB) ดังนั้นจึงไม่น่าจะเป็นปัญหาเมื่อต้องสร้างจำนวนมาก ของเธรด เป็นที่ชัดเจนว่าหน่วยความจำที่มีอยู่ยังคงเป็นข้อจำกัดที่อาจเกิดขึ้น Testlimit เวอร์ชัน 64 บิต (Testlimit64.exe) สามารถสร้างเธรดได้ประมาณ 6600 เธรดบนระบบที่มี Windows XP 64 บิตและ RAM 256MB โดยมีและไม่มีตัวเลือก -n ซึ่งเหมือนกับเวอร์ชัน 32 บิตทุกประการ สร้างขึ้นเนื่องจากถึงขีดจำกัดหน่วยความจำที่มีอยู่แล้ว อย่างไรก็ตาม บนระบบที่มี RAM ขนาด 2GB Testlimit64 สามารถสร้างได้เพียง 55,000 เธรดเท่านั้น ซึ่งน้อยกว่าจำนวนเธรดที่ยูทิลิตี้นี้สามารถสร้างได้อย่างมาก หากข้อจำกัดคือหน่วยความจำที่มีอยู่ (2GB/24KB = 89,000):

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

ข้อจำกัดของกระบวนการ
จำนวนกระบวนการที่ Windows รองรับควรน้อยกว่าจำนวนเธรดอย่างเห็นได้ชัด เนื่องจากแต่ละกระบวนการมีหนึ่งเธรดและกระบวนการเองทำให้เกิดการใช้ทรัพยากรเพิ่มเติม Testlimit 32 บิตที่ทำงานบนระบบที่มี Windows XP 64 บิตและหน่วยความจำระบบ 2GB สร้างกระบวนการประมาณ 8400 กระบวนการ:

หากคุณดูผลลัพธ์ของเคอร์เนลดีบักเกอร์ จะเห็นได้ชัดว่าในกรณีนี้ ถึงขีดจำกัดของหน่วยความจำที่มีอยู่แล้ว:

หากกระบวนการต้องใช้หน่วยความจำที่มีอยู่เพื่อรองรับเฉพาะสแต็กของเธรดในโหมดสิทธิพิเศษ Testlimit จะสามารถสร้างเธรดได้มากกว่า 8400 เธรดบนระบบ 2GB จำนวนหน่วยความจำที่มีอยู่ในระบบนี้โดยไม่ได้รัน Testlimit คือ 1.9GB:

เมื่อหารจำนวนหน่วยความจำประจำถิ่นที่ใช้โดย Testlimit (1.9 GB) ด้วยจำนวนกระบวนการที่สร้างขึ้น เราพบว่าแต่ละกระบวนการมีหน่วยความจำประจำถิ่น 230 KB เนื่องจากเคอร์เนลสแต็ก 64 บิตใช้พื้นที่ 24 KB เราจึงสูญเสียพื้นที่ประมาณ 206 KB ต่อกระบวนการ หน่วยความจำ Resident ที่ใช้แล้วที่เหลืออยู่ที่ไหน? เมื่อมีการสร้างกระบวนการ Windows จะสำรองหน่วยความจำกายภาพเพียงพอที่จะจัดเตรียมชุดเพจการทำงานขั้นต่ำ สิ่งนี้ทำเพื่อให้แน่ใจว่ากระบวนการในทุกสถานการณ์จะมีหน่วยความจำกายภาพเพียงพอในการกำจัดเพื่อจัดเก็บข้อมูลจำนวนที่จำเป็นเพื่อให้มีชุดเพจการทำงานขั้นต่ำ ตามค่าเริ่มต้น ขนาดของชุดการทำงานของเพจมักจะอยู่ที่ 200KB ซึ่งสามารถตรวจสอบได้อย่างง่ายดายโดยการเพิ่มคอลัมน์ชุดการทำงานขั้นต่ำในหน้าต่าง Process Explorer:

6Kb ที่เหลือเป็นหน่วยความจำที่มีอยู่ ซึ่งจัดสรรให้กับหน่วยความจำที่ไม่สามารถเพจได้เพิ่มเติม (จากหน่วยความจำที่ไม่สามารถเพจได้ในภาษาอังกฤษ) ซึ่งกระบวนการนั้นจะถูกจัดเก็บไว้ กระบวนการบน Windows 32 บิตใช้หน่วยความจำภายในน้อยกว่าเล็กน้อยเนื่องจากสแต็กสิทธิพิเศษของเธรดมีขนาดเล็กกว่า

เช่นเดียวกับสแต็กเธรดโหมดผู้ใช้ กระบวนการสามารถแทนที่ขนาดหน้าชุดการทำงานเริ่มต้นได้โดยใช้ฟังก์ชัน SetProcessWorkingSetSize Testlimit รองรับตัวเลือก -n ซึ่งเมื่อใช้ร่วมกับตัวเลือก -p จะทำให้คุณสามารถตั้งค่าขนาดต่ำสุดที่เป็นไปได้ของชุดการทำงานของเพจเป็น 80Kb สำหรับกระบวนการลูกของกระบวนการ Testlimit หลัก เนื่องจากกระบวนการย่อยต้องใช้เวลาในการลดชุดเพจการทำงาน Testlimit หลังจากที่ไม่สามารถวางกระบวนการ หยุดชั่วคราว และพยายามทำงานต่อไปได้อีกต่อไป ทำให้กระบวนการย่อยมีโอกาสดำเนินการ Testlimit เปิดตัวด้วยพารามิเตอร์ -n บนระบบที่ใช้ Windows 7 และ RAM ขนาด 4GB มีขีดจำกัดที่แตกต่างจากขีดจำกัดหน่วยความจำที่มีอยู่ภายใน - ขีดจำกัดของหน่วยความจำระบบที่จัดสรร:

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

ก่อนที่จะรัน Testlimit การจัดสรรหน่วยความจำโดยเฉลี่ยจะอยู่ที่ประมาณ 1.5GB ดังนั้นเธรดจึงใช้หน่วยความจำที่จัดสรรประมาณ 8GB ดังนั้น แต่ละกระบวนการจึงใช้พื้นที่ประมาณ 8 GB/6600 หรือ 1.2 MB เอาต์พุตของคำสั่งเคอร์เนลดีบักเกอร์!vm ซึ่งแสดงการกระจาย หน่วยความจำของตัวเอง(จากหน่วยความจำส่วนตัวภาษาอังกฤษ) สำหรับแต่ละกระบวนการยืนยันความถูกต้องของการคำนวณนี้:

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

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

ในบทความนี้เราจะพูดถึงหัวข้อต่างๆ เช่น กระบวนการและเธรด, ตัวอธิบายกระบวนการ, มาพูดถึง การซิงโครไนซ์กระแสและมาสัมผัสถึงรายการโปรดของทุกคนกัน ตัวจัดการงานของ windows.

ตลอดการดำรงอยู่ กระบวนการการดำเนินการสามารถถูกขัดจังหวะและดำเนินต่อไปได้หลายครั้ง เพื่อดำเนินการต่อไป กระบวนการจำเป็นต้องคืนค่าสถานะของสภาพแวดล้อมการทำงาน สถานะของสภาพแวดล้อมการทำงานจะแสดงตามสถานะของรีจิสเตอร์และตัวนับโปรแกรม โหมดการทำงานของโปรเซสเซอร์ ตัวชี้เพื่อเปิดไฟล์ ข้อมูลเกี่ยวกับการดำเนินการ I/O ที่ยังไม่เสร็จ รหัสข้อผิดพลาดของการเรียกระบบที่ดำเนินการโดยกระบวนการนี้ ฯลฯ ข้อมูลนี้เรียกว่า บริบทกระบวนการ.

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

คำอธิบาย –พิเศษ โครงสร้างข้อมูลซึ่งเริ่มต้นสำหรับแต่ละกระบวนการ (ตัวอธิบายงาน บล็อกควบคุมงาน)

โดยทั่วไป ตัวอธิบายประกอบด้วยข้อมูลต่อไปนี้:

  1. รหัสกระบวนการ
  2. ประเภทกระบวนการ (หรือคลาส) ที่กำหนดกฎการจัดเตรียมทรัพยากรบางอย่างสำหรับผู้บังคับบัญชา
  3. ลำดับความสำคัญของกระบวนการ
  4. ตัวแปรสถานะที่กำหนดว่ากระบวนการอยู่ในสถานะใด (พร้อมที่จะรัน กำลังรัน กำลังรออุปกรณ์ I/O ฯลฯ)
  5. พื้นที่หน่วยความจำที่ได้รับการป้องกัน (หรือที่อยู่ของโซนดังกล่าว) ซึ่งค่าปัจจุบันของการลงทะเบียนตัวประมวลผลจะถูกจัดเก็บหากกระบวนการถูกขัดจังหวะโดยไม่ได้ทำงานให้เสร็จสิ้น ข้อมูลนี้เรียกว่า บริบทของงาน.
  6. ข้อมูลเกี่ยวกับทรัพยากรที่กระบวนการเป็นเจ้าของและ/หรือมีสิทธิ์ใช้ (ตัวชี้เพื่อเปิดไฟล์ ข้อมูลเกี่ยวกับการดำเนินการ I/O ที่รอดำเนินการ ฯลฯ)
  7. สถานที่ (หรือที่อยู่) สำหรับจัดระเบียบการสื่อสารกับกระบวนการอื่น
  8. พารามิเตอร์เวลาเริ่มต้น (ช่วงเวลาที่ควรเปิดใช้งานกระบวนการและความถี่ของขั้นตอนนี้)
  9. ในกรณีที่ไม่มีระบบการจัดการไฟล์ ที่อยู่ของงานบนดิสก์ในสถานะเริ่มต้น และที่อยู่ในดิสก์ที่จะยกเลิกการโหลดจาก RAM หากมีการแทนที่ด้วยอย่างอื่น

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

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

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

ตัวอย่างเช่น อาจมีสถานะรอการดำเนินการ I/O ให้เสร็จสิ้นได้มากเท่ากับที่มีอุปกรณ์ I/O อยู่ในระบบ

กระบวนการและเธรด

เพื่อรองรับการทำงานหลายโปรแกรม ระบบปฏิบัติการจะต้องกำหนดและออกแบบหน่วยการทำงานภายในที่จะแบ่งโปรเซสเซอร์และทรัพยากรคอมพิวเตอร์อื่นๆ ออกไป ปัจจุบันระบบปฏิบัติการส่วนใหญ่กำหนดหน่วยงานไว้ 2 ประเภท ได้แก่

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

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

เพื่อเพิ่มความเร็วของกระบวนการ คุณสามารถใช้ความเท่าเทียมภายในในกระบวนการได้ กระบวนการ.

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

สามารถระบุความแตกต่างต่อไปนี้ได้ เธรดจากกระบวนการ:

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

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

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

ตัวจัดการงานของ WINDOWS

Task Manager แสดงข้อมูลเกี่ยวกับโปรแกรมและ กระบวนการดำเนินการบนคอมพิวเตอร์ คุณยังสามารถดูตัวชี้วัดประสิทธิภาพของกระบวนการที่ใช้บ่อยที่สุดได้ที่นั่น

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

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

บนแท็บ กระบวนการแสดงข้อมูลเกี่ยวกับกระบวนการที่ทำงานบนคอมพิวเตอร์: ข้อมูลเกี่ยวกับการใช้งาน CPU และหน่วยความจำ ตัวนับกระบวนการ และพารามิเตอร์อื่นๆ:

บนแท็บประสิทธิภาพ ข้อมูลเกี่ยวกับตัวอธิบายและเธรด พารามิเตอร์หน่วยความจำจะแสดง:

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

การซิงโครไนซ์เธรดและกระบวนการประกอบด้วยการประสานความเร็วโดยการระงับการไหลจนกว่าจะเกิดเหตุการณ์บางอย่างและการเปิดใช้งานในภายหลังเมื่อเกิดเหตุการณ์นี้

การละเลยปัญหาการซิงโครไนซ์ในระบบแบบมัลติเธรดอาจนำไปสู่ปัญหาได้ การตัดสินใจที่ผิดงานหรือแม้แต่ระบบล่ม

ตัวอย่าง - งานดูแลรักษาฐานข้อมูลลูกค้าสำหรับองค์กรบางแห่ง

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

  • Thread A ซึ่งป้อนข้อมูลคำสั่งซื้อที่ได้รับจากลูกค้าลงในฐานข้อมูล
  • หัวข้อ B ซึ่งบันทึกข้อมูลฐานข้อมูลเกี่ยวกับการชำระเงินของลูกค้าตามใบแจ้งหนี้

เธรดทั้งสองนี้ทำงานร่วมกันบนไฟล์ฐานข้อมูลทั่วไปโดยใช้อัลกอริธึมประเภทเดียวกัน:

  1. อ่านบันทึกที่มีตัวระบุที่กำหนดจากไฟล์ฐานข้อมูลลงในบัฟเฟอร์บนไคลเอนต์
  2. ป้อนค่าใหม่ในฟิลด์คำสั่งซื้อ (สำหรับขั้นตอน A) หรือการชำระเงิน (สำหรับขั้นตอน B)
  3. ส่งกลับบันทึกที่แก้ไขไปยังไฟล์ฐานข้อมูล

ให้เราแสดงขั้นตอนที่ 1-3 สำหรับโฟลว์ A เป็น A1-A3 และสำหรับโฟลว์ B เป็น B1-B3 สมมติว่า ณ จุดหนึ่งเธรด A จะอัพเดตฟิลด์ Order ของเรกคอร์ดเกี่ยวกับลูกค้า N เมื่อต้องการทำเช่นนี้ A จะอ่านเรกคอร์ดนี้ลงในบัฟเฟอร์ (ขั้นตอน A1) แก้ไขค่าของฟิลด์ Order (ขั้นตอน A2) แต่ไม่ มีเวลาเพิ่มบันทึกลงในฐานข้อมูล เนื่องจากการดำเนินการถูกขัดจังหวะ เช่น เนื่องจากการหมดอายุของการแบ่งเวลา

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

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

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

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

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

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

หากทรัพยากรไม่ว่าง กระบวนการจะไม่ดำเนินการสำรวจแบบวนรอบ แต่เรียกใช้ฟังก์ชันระบบ WAIT(D) ในที่นี้ D หมายถึงเหตุการณ์ที่รีซอร์ส D ถูกรีลีส ฟังก์ชัน WAIT(D) จะวางกระบวนการที่ใช้งานอยู่ใน WAITING ระบุสถานะและจดบันทึกไว้ในคำอธิบายว่ากระบวนการกำลังรอเหตุการณ์ D กระบวนการที่กำลังใช้ทรัพยากร D อยู่ในขณะนี้ หลังจากออกจากส่วนที่วิกฤตแล้ว จะดำเนินการฟังก์ชันระบบ POST(D) ซึ่งเป็นผลมาจากระบบปฏิบัติการ สแกนคิวของกระบวนการรอและทำให้กระบวนการรอเหตุการณ์ D อยู่ในสถานะ READY

วิธีการทั่วไปของกระบวนการซิงโครไนซ์ถูกเสนอโดย Dijkstra ซึ่งแนะนำวิธีดั้งเดิมใหม่สองประการ ในรูปแบบนามธรรม ค่าพื้นฐานเหล่านี้แสดงด้วย P และ V ดำเนินการกับตัวแปรจำนวนเต็มที่ไม่เป็นลบที่เรียกว่า เซมาฟอร์- ให้ S เป็นสัญญาณดังกล่าว การดำเนินงานมีการกำหนดดังนี้:

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

P(S): ลด S ลง 1 ถ้าเป็นไปได้ ถ้า S=0 เป็นไปไม่ได้ที่จะลด S และยังคงอยู่ในขอบเขตของค่าจำนวนเต็มที่ไม่เป็นลบ ซึ่งในกรณีนี้ กระบวนการที่เรียกใช้การดำเนินการ P จะรอจนกระทั่งการลดลงนี้เกิดขึ้นได้ การตรวจสอบและลดขนาดได้สำเร็จถือเป็นการดำเนินการที่แบ่งแยกไม่ได้เช่นกัน

ในกรณีพิเศษที่เซมาฟอร์ S สามารถรับได้เฉพาะค่า 0 และ 1 เท่านั้น จะกลายเป็นตัวแปรการบล็อก การดำเนินการ P มีศักยภาพที่จะทำให้กระบวนการที่กำลังดำเนินการอยู่ในสถานะรอ ในขณะที่การดำเนินการ V อาจเปิดใช้งานกระบวนการอื่นที่ถูกระงับโดยการดำเนินการ P ในบางกรณี

กระบวนการหยุดชะงัก

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

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

ในระบบมัลติทาสกิ้ง กระบวนการหนึ่งถูกกล่าวว่าจะหยุดชะงักหากกำลังรอเหตุการณ์ที่จะไม่เกิดขึ้น

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

ปัญหาการชะงักงันรวมถึงงานต่อไปนี้:

  1. ป้องกันการหยุดชะงัก
  2. การรับรู้การหยุดชะงัก
  3. การกู้คืนระบบหลังจากการหยุดชะงัก

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

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

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