goroutine พูลเป็นแบบเธรดสีเขียวหรือไม่


47

ผู้วิจารณ์ที่นี่เสนอคำวิจารณ์ต่อไปนี้ของหัวข้อสีเขียว:

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

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

บทวิจารณ์อื่นอยู่ที่นี่ :

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

คำถามของฉัน - จะไป lang ของ goroutines (สำหรับสระว่ายน้ำเริ่มต้น) เพียงหัวข้อสีเขียว? ถ้าเป็นเช่นนั้นพวกเขาจะจัดการกับคำวิจารณ์ข้างต้นหรือไม่

คำตอบ:


67

ฉันเป็นแค่ผู้ใช้ 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 และการนำไปใช้ในปัจจุบันส่วนใหญ่เน้นการวิพากษ์วิจารณ์เหล่านี้


1
การตอบคำถามที่ยอดเยี่ยมและมีรายละเอียด :)
Tuxdude

1
ฉันชอบคำตอบนี้ แต่คุณมีการอ้างอิงถึงวิธีการ / เธรด OS ที่ถูกสร้างขึ้นหรือไม่?
ลาร์ส

1
หนึ่งในข้อเสียที่ใหญ่ที่สุดของ Go Language คือมันสร้างเธรดเคอร์เนลสำหรับทุกการเรียกของระบบบล็อก!
user1870400

8
โปรดทราบว่าบทความ“ green thread” ใน Wikipedia ได้ถูกเปลี่ยนเป็นสถานะ“ threads ที่กำหนดเวลาไว้โดยruntime libraryหรือ virtual machine (VM)”; ซึ่งหมายความว่าตามคำนิยามนั้นคำตอบของคุณจะไม่ถูกต้องอีกต่อไปเนื่องจากรันไทม์ของ Go ทำการตั้งเวลา / จัดการ ฉันคิดว่าการกำหนดเธรดสีเขียวมีประโยชน์มากขึ้นเมื่อเธรดพื้นที่ผู้ใช้ตัดกับเธรด OS และจากนั้นใช่ goroutines เป็นหัวข้อสีเขียวแน่นอน
mknecht

1
อันดับ 2 @mknecht มันไม่เกี่ยวกับ VM มันเกี่ยวกับ runtime และไปแน่นอนมีรันไทม์ (ซึ่งจัดการรูปแบบเธรดและการรวบรวมขยะ)
Tim Harper
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.