ทำไมไม่ Green Threads


33

ในขณะที่ฉันรู้ว่าคำถามนี้ได้รับการครอบคลุมแล้ว (เช่นhttps://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ) ฉันไม่รู้สึกว่าฉันได้รับคำตอบที่น่าพอใจ .

คำถามคือ: ทำไม JVM ไม่สนับสนุนเธรดสีเขียวอีกต่อไป?

มันบอกว่านี้ในแบบโค้ด Java คำถามที่พบบ่อย :

เธรดสีเขียวหมายถึงโหมดการทำงานของ Java Virtual Machine (JVM) ซึ่งโค้ดทั้งหมดจะถูกดำเนินการในเธรดระบบปฏิบัติการเดียว

และสิ่งนี้จบบนjava.sun.com :

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

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

คิด?


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

4
มันเกี่ยวกับการมีรูปแบบการเขียนโปรแกรมพร้อมกันซึ่งขนาด ปัจจุบันใน Java หากคุณต้องการความยืดหยุ่นในการปรับขนาดคุณเปลี่ยนเป็น NIO ด้วยเธรดพูลของคุณเอง อย่างน้อยนั่นคือความเข้าใจของฉัน
redjamjar

3
การมีสิ่งต่าง ๆ เช่น < akka.io > ที่รองรับเธรดที่มีน้ำหนักเบายังทำให้ฉันคิดว่ามีความต้องการ จริง ๆ แล้วเพิ่งพบการสนทนาที่ดีที่นี่ < stackoverflow.com/questions/7458782/… >
redjamjar

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

ใช้เวลานานก่อนที่ JVM จะรองรับเธรดดั้งเดิมโดยตรง หัวข้อสีเขียวเป็นวิธีการแก้ปัญหาระดับกลางจนกระทั่งแล้ว
Thorbjørn Ravn Andersen

คำตอบ:


29

ฉันจำ JVM ที่ละทิ้งเธรดสีเขียวและย้ายไปที่เธรดดั้งเดิม ด้วยเหตุผลง่ายๆสองข้อ: เธรดสีเขียวเป็นขยะตรงไปตรงมาและมีความต้องการที่จะสนับสนุนโปรเซสเซอร์แบบมัลติคอร์ด้วยความพยายามของนักพัฒนาที่ จำกัด ที่ซัน

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

  • พวกเขาจะต้องใช้แกน cpu ทั้งหมดที่มีให้

  • การสลับบริบทต้องมีราคาถูก

  • I / O อาจบล็อกเธรดที่มีส่วนร่วม แต่ไม่ใช่เธรดอื่นใดและไม่แน่นอนเธรดอื่นทั้งหมดซึ่งเป็นกรณีในการนำไปใช้ก่อนหน้านี้บางส่วน

ฉันมักจะสงสัยว่าทำไมการมัลติเธรดจึงยากใน Java แต่ตอนนี้มันชัดเจนยิ่งขึ้น - ในที่สุดมันก็เกี่ยวกับการเปลี่ยนไปใช้เธรดดั้งเดิมซึ่งก็คือ:

  • เก่งในการใช้แกน cpu ทั้งหมด

  • เก่งในการเป็นพร้อมกันอย่างแท้จริงให้ I / O อิสระเป็นต้น

  • ช้าที่การสลับบริบท (เปรียบเทียบกับการใช้เธรดสีเขียวที่ดีที่สุด)

  • ความโลภอย่างน่ากลัวด้วยความทรงจำ จำกัด จำนวนสูงสุดที่สามารถใช้ได้

  • สิ่งที่เป็นนามธรรมที่น่าสงสารสำหรับพื้นฐานสำหรับการแสดงโลกแห่งความจริงซึ่งแน่นอนพร้อมกันอย่างมาก

ปัจจุบันมีจำนวนมากของเวลาโปรแกรมเมอร์ในขณะนี้จะเข้าสู่การเขียนโปรแกรมขึ้น non-blocking I / O, ฟิวเจอร์สและอื่น ๆ มันเป็นความอัปยศใหญ่ที่เราไม่ได้อยู่ในระดับที่ดีขึ้นของสิ่งที่เป็นนามธรรม

สำหรับการเปรียบเทียบนอกจากภาษา Erlang แล้วภาษาGoใหม่ยังทำงานได้ดีในเวลาเดียวกัน พ่อของพวกเขาทุกคนยังคงเกิดขึ้นในรัฐปรากยังเป็นโครงการวิจัยที่กำลังดำเนินอยู่


เราไปได้ไกลแค่ไหนตั้งแต่คุณโพสต์: O
Dmitry

3
อนิจจารอยสนิมเป็นอีกภาษาหนึ่งที่ทิ้งรูปแบบการทำงานพร้อมกันที่ดีกว่า พวกเขาตัดสินใจย้ายจากเธรดที่ทำงานร่วมกันไปที่เธรดดั้งเดิม
Rick-777

2
@ Rick-777 Rust ต่ำเกินไปที่จะทำ
Malcolm

15

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

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

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


Occam อ้างว่าจะเสนอสิ่งนี้ มันเป็นภาษาที่สำคัญในยุค 80 แต่ได้รับความเดือดร้อนจากการขาดเงินทุนในการพัฒนาและกลายเป็นช่องทางการวิจัยเท่านั้น แต่ความคิดเกี่ยวกับการเกิดขึ้นพร้อมกันนั้นมั่นคงในขณะนี้เหมือนที่เคยเป็นมาและยังไม่ได้รับการปรับปรุง
Rick-777

หากคุณเป็น "การกำหนดเวลาแบบมัลติเธรด" a la golang ("M: N" การจัดตารางเวลาประเภท) ในทางทฤษฎีแล้วจะมีเธรดสีเขียวเพียงหนึ่งเธรดที่ถูกบล็อกโดยความผิดพลาดของเพจเนื่องจากเธรดอื่น ๆ สามารถ .. softwareengineering.stackexchange.com/questions/222642/…
rogerdpack

13

จะไม่มีประโยชน์เลยสำหรับรหัส Java เฉลี่ย Java ไม่ใช่ Erlang และโปรแกรมเมอร์ Java ไม่ได้อยู่ในความคิดเดียวกันกับโปรแกรมเมอร์ Erlang ภาษาไม่เคยตั้งใจจะใช้วิธีนี้

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


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

1
@redjamjar มันไม่น่าจะมีประโยชน์ใน Java, ภาษาตัวเองไม่เหมาะสำหรับการใช้งานและประโยชน์หลัก (และเท่านั้น) - ส่วนใหญ่ของห้องสมุดพร้อมที่จะใช้ - ไม่เหมาะกับคนต่างด้าวดังกล่าว วิธีการเขียนโปรแกรม
SK-logic

ใช่ถ้าคุณต้องการโมเดลนั้นเพียงใช้ Erlang มันจะเป็นลำดับความสำคัญได้ง่ายขึ้น
Zachary K

1
! Java = JVM, แค่บอก :)
Kamil Tomšík

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