อะไรคือความแตกต่างระหว่าง "coroutine" และ "ด้าย"?
อะไรคือความแตกต่างระหว่าง "coroutine" และ "ด้าย"?
คำตอบ:
Coroutines เป็นรูปแบบของการประมวลผลตามลำดับ: มีเพียงอันเดียวเท่านั้นที่ดำเนินการในเวลาที่กำหนด
เธรดคือรูปแบบของการประมวลผลที่เกิดขึ้นพร้อมกัน (อย่างน้อยที่สุดแนวคิด): หลายเธรดอาจกำลังดำเนินการในเวลาใดก็ตาม (เดิมบน CPU เดียว, เครื่อง single-core พร้อมกันที่จำลองด้วยความช่วยเหลือจากระบบปฏิบัติการ - ปัจจุบันตั้งแต่ดังนั้นหลายเครื่องมีหลาย CPU และ / หรือแบบ multi-core, หัวข้อจะพฤตินัยจะดำเนินการพร้อมกัน ไม่เพียง "แนวคิด")
อ่านครั้งแรก: เห็นพ้องด้วยกับความเท่าเทียม - ความแตกต่างคืออะไร?
การเกิดขึ้นพร้อมกันคือการแยกของงานเพื่อให้การดำเนินการ interleaved Parallelism เป็นการทำงานหลายชิ้นพร้อมกันเพื่อเพิ่มความเร็ว - https://github.com/servo/servo/wiki/Design
คำตอบสั้น ๆ :ด้วยเธรดระบบปฏิบัติการจะสลับการทำงานของเธรดล่วงหน้าตามตัวกำหนดตารางเวลาซึ่งเป็นอัลกอริทึมในเคอร์เนลระบบปฏิบัติการ ด้วย coroutines โปรแกรมเมอร์และภาษาการเขียนโปรแกรมจะกำหนดเวลาที่จะเปลี่ยน coroutines กล่าวอีกนัยหนึ่งคือการทำงานหลายอย่างพร้อมกันโดยการหยุดชั่วคราวและทำงานต่อที่จุดที่ตั้งไว้โดยทั่วไป (แต่ไม่จำเป็น) ภายในเธรดเดี่ยว
คำตอบยาว:ในทางตรงกันข้ามกับเธรดซึ่งกำหนดไว้ล่วงหน้าโดยระบบปฏิบัติการสวิตช์ coroutine เป็นแบบร่วมมือหมายถึงโปรแกรมเมอร์ (และภาษาการเขียนโปรแกรมและรันไทม์) ควบคุมเมื่อสวิตช์เกิดขึ้น
ตรงกันข้ามกับเธรดซึ่งเป็น pre-emptive สวิตช์ coroutine นั้นทำงานร่วมกัน (โปรแกรมเมอร์ควบคุมเมื่อสวิตช์เกิดขึ้น) เคอร์เนลไม่ได้เกี่ยวข้องกับสวิตช์ coroutine - http://www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html/coroutine/overview.html
ภาษาที่รองรับเธรดดั้งเดิมสามารถเรียกใช้เธรด (เธรดผู้ใช้) บนเธรดของระบบปฏิบัติการ ( เคอร์เนลเธรด ) ทุกกระบวนการมีเคอร์เนลเธรดอย่างน้อยหนึ่งเธรด เธรดเคอร์เนลเป็นเหมือนกระบวนการยกเว้นว่าพวกเขาแบ่งปันพื้นที่หน่วยความจำในกระบวนการการเป็นเจ้าของกับเธรดอื่น ๆ ทั้งหมดในกระบวนการนั้น กระบวนการ "เป็นเจ้าของ" ทรัพยากรที่ได้รับมอบหมายทั้งหมดเช่นหน่วยความจำด้ามจับไฟล์ซ็อกเก็ตอุปกรณ์จับ ฯลฯ และทรัพยากรเหล่านี้ใช้ร่วมกันระหว่างเคอร์เนลเธรด
ตัวกำหนดตารางเวลาระบบปฏิบัติการเป็นส่วนหนึ่งของเคอร์เนลที่รันแต่ละเธรดในเวลาจำนวนหนึ่ง (บนเครื่องตัวประมวลผลเดียว) ตัวกำหนดตารางเวลาจะจัดสรรเวลา (timeslicing) ให้กับแต่ละเธรดและถ้าเธรดไม่เสร็จภายในเวลานั้นตัวจัดกำหนดการล่วงหน้าจะทำการ empts (ขัดจังหวะและสลับไปยังเธรดอื่น) หลายเธรดสามารถทำงานแบบขนานบนเครื่องที่มีตัวประมวลผลหลายตัวเนื่องจากแต่ละเธรดสามารถกำหนดเวลา (แต่ไม่จำเป็นต้องมี) ลงบนตัวประมวลผลแยกต่างหาก
บนเครื่องตัวประมวลผลเดียวเธรดจะถูกตั้งเวลาและยึดเอาไว้ล่วงหน้า (สลับระหว่าง) อย่างรวดเร็ว (บน Linux ค่าเริ่มต้นคือ 100ms) ซึ่งทำให้พร้อมกัน อย่างไรก็ตามมันไม่สามารถทำงานแบบขนาน (พร้อมกัน) เนื่องจากโปรเซสเซอร์แบบคอร์เดียวสามารถทำงานได้ทีละอย่างเท่านั้น
Coroutinesและ / หรือเครื่องกำเนิดไฟฟ้าสามารถใช้ในการใช้ฟังก์ชั่นความร่วมมือ แทนที่จะถูกรันบนเคอร์นัลเธรดและกำหนดเวลาโดยระบบปฏิบัติการพวกมันจะรันในเธรดเดี่ยวจนกว่าพวกเขาจะให้ผลลัพธ์หรือเสร็จสิ้นยอมให้ทำหน้าที่อื่น ๆ ตามที่โปรแกรมเมอร์กำหนดไว้ ภาษากับเครื่องกำเนิดเช่น Python และ ECMAScript 6 สามารถใช้เพื่อสร้าง coroutines Async / await (เห็นใน C #, Python, ECMAscript 7, Rust) เป็นนามธรรมที่สร้างขึ้นจากฟังก์ชั่นเครื่องกำเนิดไฟฟ้าที่สร้างอนาคต / สัญญา
ในบางบริบทcoroutinesอาจอ้างถึงฟังก์ชั่นที่กองซ้อนในขณะที่เครื่องกำเนิดไฟฟ้าอาจหมายถึงฟังก์ชั่นที่ซ้อนกัน
Fibres , เธรดที่มีน้ำหนักเบาและเธรดสีเขียวเป็นชื่ออื่นสำหรับ coroutine หรือสิ่งที่คล้ายกับ coroutine บางครั้งพวกเขาอาจมีลักษณะเหมือนกันกับเธรดระบบปฏิบัติการในภาษาการเขียนโปรแกรม แต่โดยทั่วไปแล้วพวกเขาจะไม่ได้ทำงานแบบขนานเหมือนเธรดจริงและทำงานแทน coroutines (อาจมีลักษณะเฉพาะทางเทคนิคที่เฉพาะเจาะจงมากขึ้นหรือความแตกต่างระหว่างแนวคิดเหล่านี้ขึ้นอยู่กับภาษาหรือการใช้งาน)
ตัวอย่างเช่น Java มี " หัวข้อสีเขียว "; เหล่านี้คือเธรดที่กำหนดเวลาโดย Java virtual machine (JVM) แทนที่จะเป็นแบบดั้งเดิมบนเธรดเคอร์เนลของระบบปฏิบัติการ สิ่งเหล่านี้ไม่ได้ทำงานแบบขนานหรือใช้ประโยชน์จากโปรเซสเซอร์ / คอร์หลายตัว - เนื่องจากจะต้องใช้เธรดดั้งเดิม! เนื่องจากไม่มีการกำหนดตารางเวลาโดยระบบปฏิบัติการจึงเป็นเหมือน coroutines มากกว่าเคอร์เนลเธรด กรีนเธรดคือสิ่งที่ Java ใช้จนกระทั่งเธรดดั้งเดิมถูกนำเข้าสู่ Java 1.2
เธรดใช้ทรัพยากร ใน JVM แต่ละเธรดจะมีสแต็กของตนเองซึ่งโดยทั่วไปจะมีขนาด 1MB 64k เป็นจำนวนพื้นที่สแต็กน้อยที่สุดที่อนุญาตต่อเธรดใน JVM ขนาดเธรดสแต็กสามารถกำหนดค่าบนบรรทัดคำสั่งสำหรับ JVM แม้จะมีชื่อเธรดไม่ว่างเนื่องจากทรัพยากรการใช้งานเช่นแต่ละเธรดที่ต้องการสแต็กของตนเองหน่วยเก็บข้อมูลเธรดโลคัล (ถ้ามี) และต้นทุนของการทำให้ใช้แคชการกำหนดเวลาเธรด / การสลับบริบท นี่เป็นส่วนหนึ่งของสาเหตุที่ทำให้ coroutines กลายเป็นที่นิยมสำหรับแอพพลิเคชั่นที่สำคัญและมีประสิทธิภาพสูง
Mac OS จะอนุญาตให้กระบวนการจัดสรรเธรดประมาณ 2000 เธรดเท่านั้นและ Linux จะจัดสรรสแต็ก 8MB ต่อเธรดและจะอนุญาตเฉพาะเธรดจำนวนมากที่พอดีกับ RAM จริง
ดังนั้นเธรดมีน้ำหนักมากที่สุด (ในแง่ของการใช้หน่วยความจำและเวลาการสลับบริบท) จากนั้น coroutines และในที่สุดเครื่องกำเนิดไฟฟ้าก็จะมีน้ำหนักเบาที่สุด
ประมาณ 7 ปีที่ผ่านมา แต่คำตอบที่นี่หายไปบางส่วนของบริบทร่วมกับเธรด ทำไมcoroutines ถึงได้รับความสนใจอย่างมากเมื่อเร็ว ๆ นี้และเมื่อใดที่ฉันจะใช้มันเปรียบเทียบกับเธรด ?
ก่อนอื่นถ้า coroutines ทำงานพร้อมกัน (ไม่ขนาน ) ทำไมใครถึงชอบมันมากกว่าเธรด?
คำตอบก็คือ coroutines สามารถให้ระดับที่สูงมากเห็นพ้องกับค่าใช้จ่ายน้อยมาก โดยทั่วไปในสภาพแวดล้อมเกลียวคุณมีที่มากที่สุด 30-50 กระทู้ก่อนจำนวนเงินของการสูญเสียค่าใช้จ่ายจริงการตั้งเวลาหัวข้อเหล่านี้ (โดยการจัดตารางเวลาระบบน) อย่างมีนัยสำคัญการปรับลดลงในระยะเวลาที่หัวข้อจริงจะทำงานที่เป็นประโยชน์
ตกลงกับเธรดที่คุณสามารถมีความเท่าเทียมกัน แต่ไม่ขนานกันมากเกินไปนั่นก็ยังดีกว่าการทำงานร่วมแบบร่วมในเธรดเดียวใช่ไหม ก็ไม่จำเป็น โปรดจำไว้ว่าการร่วมงานประจำยังคงสามารถทำงานพร้อมกันได้โดยไม่ต้องมีค่าใช้จ่ายในการจัดกำหนดการ
ตัวอย่างเช่นถ้าคุณมีกิจวัตรประจำวันที่จะทำงานบางอย่างและมันจะทำการดำเนินการที่คุณรู้ว่าจะปิดกั้นบางครั้ง (เช่นคำขอเครือข่าย) ด้วย co-กิจวัตรคุณสามารถสลับไปที่กิจวัตรอื่นได้ทันทีโดยไม่ต้องมีค่าใช้จ่าย การตัดสินใจนี้ - ใช่คุณโปรแกรมเมอร์ต้องระบุว่าเมื่อใดที่กิจวัตรร่วมสามารถเปลี่ยนได้
ด้วยงานประจำจำนวนมากที่ทำงานชิ้นเล็ก ๆ น้อย ๆ และสลับกันโดยสมัครใจคุณก็มาถึงระดับของประสิทธิภาพที่ไม่มีตัวกำหนดตารางเวลาที่จะทำให้สำเร็จ ตอนนี้คุณสามารถมี coroutines หลายพันตัวทำงานร่วมกันแทนที่จะเป็นสิบกระทู้
เนื่องจากตอนนี้กิจวัตรของคุณสลับกันเป็นจุดที่กำหนดไว้ล่วงหน้าคุณจึงสามารถหลีกเลี่ยงการล็อคโครงสร้างข้อมูลที่ใช้ร่วมกันได้ (เพราะคุณจะไม่บอกรหัสของคุณให้สลับไปยัง coroutine อื่นที่อยู่ตรงกลางของส่วนสำคัญ)
ข้อดีอีกอย่างคือการใช้หน่วยความจำต่ำกว่ามาก ด้วย threaded-model แต่ละเธรดจำเป็นต้องจัดสรรสแต็กของตัวเองและเพื่อให้การใช้หน่วยความจำของคุณเพิ่มขึ้นเป็นเส้นตรงตามจำนวนเธรดที่คุณมี ด้วย co-routines จำนวนของรูทีนที่คุณไม่มีความสัมพันธ์โดยตรงกับการใช้หน่วยความจำของคุณ
และในที่สุด co-routines ก็ได้รับความสนใจเป็นอย่างมากเพราะในบางภาษาการเขียนโปรแกรม (เช่น Python) เธรดของคุณไม่สามารถทำงานแบบขนานได้ - พวกมันทำงานพร้อมกันเหมือนกับ coroutines แต่ไม่มีหน่วยความจำต่ำและค่าใช้จ่ายในการตั้งเวลาว่าง
ในคำ: ใบจอง Coroutines ทำตัวเหมือนนักเล่นกลที่คอยส่งต่อคะแนนที่ถูกซ้อมมาอย่างต่อเนื่อง เธรด (เธรดที่แท้จริง) สามารถถูกขัดจังหวะได้เกือบทุกจุดแล้วกลับมาทำงานต่อในภายหลัง แน่นอนว่าสิ่งนี้นำมาซึ่งปัญหาความขัดแย้งด้านทรัพยากรทุกประเภทดังนั้น GIL ที่น่าอับอายของ Python - Global Interpreter Lock
การปรับใช้เธรดจำนวนมากนั้นแท้จริงแล้วเหมือนกับ coroutines
ขึ้นอยู่กับภาษาที่คุณใช้ ยกตัวอย่างเช่นใน Lua พวกมันเหมือนกัน (เรียกว่า coroutine ชนิดตัวแปรthread
)
โดยทั่วไปแม้ว่า coroutines จะใช้ความสมัครใจในการที่โปรแกรมเมอร์จะเป็นผู้ตัดสินใจว่าจะyield
ให้การควบคุมไปที่รูทีนอื่น
เธรดจะได้รับการจัดการโดยอัตโนมัติ (หยุดและเริ่มต้น) โดยระบบปฏิบัติการและพวกเขายังสามารถเรียกใช้ในเวลาเดียวกันบน CPU แบบมัลติคอร์
12 ปีหลังการอภิปราย แต่ coroutine มีคำอธิบายในชื่อ Coroutine สามารถย่อยสลายได้ใน Co และ Routine
รูทีนในบริบทนี้เป็นเพียงลำดับของการดำเนินการ / การกระทำและโดยการดำเนินการ / การประมวลผลตามปกติลำดับของการดำเนินการจะถูกดำเนินการทีละตัวในลำดับเดียวกันตามที่ระบุ
Co ย่อมาจากความร่วมมือ รูทีนร่วมจะถูกขอให้ (หรือคาดว่าดีกว่า) ระงับการดำเนินการด้วยความเต็มใจเพื่อให้ผู้ร่วมงานรายอื่นมีโอกาสเรียกใช้งานด้วยเช่นกัน ดังนั้นการทำงานร่วมกันเป็นเรื่องเกี่ยวกับการแบ่งปันทรัพยากร CPU (ด้วยความเต็มใจ) เพื่อให้ผู้อื่นสามารถใช้ทรัพยากรเดียวกันกับที่ตัวเองกำลังใช้อยู่
เธรดในอีกไม่จำเป็นต้องระงับการดำเนินการ การถูกระงับนั้นโปร่งใสอย่างสมบูรณ์กับเธรดและเธรดถูกบังคับโดยฮาร์ดแวร์อ้างอิงเพื่อระงับตัวเอง นอกจากนี้ยังทำในลักษณะที่ส่วนใหญ่โปร่งใสกับเธรดเนื่องจากไม่ได้รับการแจ้งเตือนและสถานะจะไม่เปลี่ยนแปลง แต่บันทึกและเรียกคืนในภายหลังเมื่อเธรดได้รับอนุญาตให้ดำเนินการต่อ
สิ่งหนึ่งที่ไม่เป็นความจริงเพื่อนร่วมงานที่ไม่สามารถดำเนินการได้พร้อมกันและสภาพการแข่งขันไม่สามารถเกิดขึ้นได้ ขึ้นอยู่กับระบบที่ใช้งานร่วมตามปกติและเป็นไปได้ง่ายในการถ่ายภาพร่วม
ไม่สำคัญว่าเพื่อนร่วมกิจวัตรจะระงับตัวเองอย่างไร ย้อนกลับไปใน Windows 3.1 int 03 ได้รวมเข้ากับโปรแกรมใด ๆ (หรือจะต้องมีอยู่ในนั้น) และใน C # เราเพิ่มผลผลิต