ฉันเป็นแค่ผู้ใช้ Go ธรรมดา ๆ ดังนั้นโปรดเอาเกลือต่อไปนี้มาด้วย
Wikipedia กำหนดเธรดสีเขียวเป็น "เธรดที่กำหนดเวลาโดยเครื่องเสมือน (VM) แทนที่จะเป็นแบบดั้งเดิมโดยระบบปฏิบัติการพื้นฐาน" เธรดสีเขียวจำลองสภาพแวดล้อมแบบมัลติเธรดโดยไม่ต้องอาศัยความสามารถของระบบปฏิบัติการดั้งเดิมและมีการจัดการในพื้นที่ผู้ใช้แทนพื้นที่เคอร์เนลทำให้พวกเขาสามารถทำงานในสภาพแวดล้อมที่ไม่มีการสนับสนุนเธรดแบบดั้งเดิม
Go (หรือมากกว่าสองอย่างของการใช้งานที่มีอยู่เดิม) เป็นภาษาที่สร้างโค้ดเนทีฟเท่านั้น - ไม่ใช้ VM นอกจากนี้ตัวกำหนดตารางเวลาในการใช้งานรันไทม์ปัจจุบันอาศัยเธรดระดับ OS (แม้ว่า GOMAXPROCS = 1) ดังนั้นฉันคิดว่าการพูดถึงเธรดสีเขียวสำหรับโมเดล Go เป็นสิ่งที่ไม่เหมาะสม
ผู้คนไปประกาศเกียรติคุณในระยะ goroutine โดยเฉพาะเพื่อหลีกเลี่ยงความสับสนกับกลไกการทำงานพร้อมกันอื่น ๆ (เช่น coroutines หรือกระทู้หรือกระบวนการที่มีน้ำหนักเบา)
แน่นอนว่า Go รองรับรูปแบบการทำเกลียว M: N แต่มันดูใกล้เคียงกับแบบจำลองกระบวนการ Erlang มากกว่าแบบจำลองเธรดสีเขียวของ Java
นี่คือประโยชน์เล็กน้อยของโมเดล Go บนเธรดสีเขียว (ตามที่ใช้ใน JVM ก่อน):
หลายคอร์หรือซีพียูสามารถใช้ได้อย่างมีประสิทธิภาพในวิธีที่โปร่งใสสำหรับนักพัฒนา ด้วย Go นักพัฒนาควรดูแลการเกิดพร้อมกัน รันไทม์ของ Go จะดูแลขนาน การประยุกต์ใช้เธรดสีเขียวของ Java ไม่ได้ปรับขนาดมากกว่าหลายคอร์หรือซีพียู
การเรียกใช้ระบบและ C ไม่ใช่การปิดกั้นสำหรับตัวกำหนดตารางเวลา (การเรียกใช้ระบบทั้งหมดไม่เพียง แต่รองรับการเรียกใช้มัลติเพล็กซ์ I / O ในเหตุการณ์ลูป) การประยุกต์ใช้เธรดสีเขียวสามารถบล็อกกระบวนการทั้งหมดเมื่อมีการเรียกระบบบล็อก
กองคัดลอกหรือแบ่งส่วน ในการไปไม่จำเป็นต้องจัดเตรียมขนาดสแต็กสูงสุดสำหรับ goroutine สแต็คเติบโตแบบค่อยเป็นค่อยไปตามต้องการ สิ่งหนึ่งที่สำคัญคือ goroutine ไม่ต้องการหน่วยความจำมาก (4KB-8KB) ดังนั้นจึงสามารถวางไข่จำนวนมากได้อย่างมีความสุข การใช้งาน Goroutine สามารถแพร่หลายได้
ตอนนี้เพื่อแก้ไขข้อวิจารณ์:
ด้วย Go คุณไม่ต้องเขียนตัวกำหนดเวลา userspace: มันมีให้กับ runtime แล้ว มันเป็นซอฟต์แวร์ที่ซับซ้อน แต่เป็นปัญหาของนักพัฒนา Go ไม่ใช่ผู้ใช้ Go การใช้งานนั้นโปร่งใสสำหรับผู้ใช้ Go ในบรรดานักพัฒนาซอฟต์แวร์ Go Dmitri Vyukovเป็นผู้เชี่ยวชาญในการเขียนโปรแกรม lockfree / waitfree และดูเหมือนว่าเขาสนใจที่จะแก้ไขปัญหาประสิทธิภาพการทำงานของตัวกำหนดตารางเวลาในที่สุด การใช้ตัวกำหนดตารางเวลาปัจจุบันไม่สมบูรณ์ แต่จะปรับปรุงให้ดีขึ้น
การซิงโครไนซ์ทำให้เกิดปัญหาประสิทธิภาพและความซับซ้อน: นี่เป็นจริงบางส่วนกับ Go เช่นกัน แต่สังเกตว่ารุ่น Go พยายามที่จะส่งเสริมการใช้งานของช่องสัญญาณและการย่อยสลายที่ชัดเจนของโปรแกรมใน goroutines ที่เกิดขึ้นพร้อมกันเพื่อจำกัดความซับซ้อนในการซิงโครไนซ์ (เช่นการแบ่งปันข้อมูลโดยการสื่อสารแทนการแชร์หน่วยความจำ โดยวิธีการที่อ้างอิงการดำเนินงานไปให้จำนวนของเครื่องมือในการปฏิบัติงานที่อยู่และเห็นพ้องด้วยปัญหาเช่นProfilerและตรวจจับการแข่งขัน
เกี่ยวกับความผิดพลาดของหน้าและ "หลายเธรดปลอม" โปรดทราบว่า Go สามารถกำหนดตารางเวลา goroutine ผ่านหลายเธรดของระบบ เมื่อเธรดหนึ่งถูกบล็อกด้วยเหตุผลใด ๆ (ความผิดพลาดของหน้าบล็อกการโทรของระบบ) จะไม่ป้องกันเธรดอื่น ๆ ที่จะกำหนดเวลาและเรียกใช้ goroutines อื่นต่อไป ตอนนี้มันเป็นความจริงที่ความผิดพลาดของหน้าจะบล็อกเธรด OS ด้วย goroutines ทั้งหมดที่ควรจะจัดตารางเวลาในเธรดนี้ อย่างไรก็ตามในทางปฏิบัติหน่วยความจำฮีปของ Go ไม่ควรถูกสลับออก สิ่งนี้จะเหมือนกันใน Java: ภาษาที่รวบรวมขยะไม่รองรับหน่วยความจำเสมือนได้เป็นอย่างดีอยู่แล้ว หากโปรแกรมของคุณต้องจัดการกับข้อผิดพลาดของหน้าอย่างสง่างามอาจเป็นเพราะมันมีการจัดการหน่วยความจำนอกกอง ในกรณีนั้น,
ดังนั้น IMO, goroutines จึงไม่ใช่หัวข้อสีเขียวและภาษา Go และการนำไปใช้ในปัจจุบันส่วนใหญ่เน้นการวิพากษ์วิจารณ์เหล่านี้