เมื่อดูที่การเขียนโปรแกรมพร้อมกันคำสองคำที่ใช้กันทั่วไปคือพร้อมกันและขนาน
และบางภาษาโปรแกรมเฉพาะเรียกร้องการสนับสนุนสำหรับการเขียนโปรแกรมแบบขนานเช่นJava
สิ่งนี้หมายความว่าการเขียนโปรแกรมแบบขนานและพร้อมกันนั้นแตกต่างกันจริงหรือ
เมื่อดูที่การเขียนโปรแกรมพร้อมกันคำสองคำที่ใช้กันทั่วไปคือพร้อมกันและขนาน
และบางภาษาโปรแกรมเฉพาะเรียกร้องการสนับสนุนสำหรับการเขียนโปรแกรมแบบขนานเช่นJava
สิ่งนี้หมายความว่าการเขียนโปรแกรมแบบขนานและพร้อมกันนั้นแตกต่างกันจริงหรือ
คำตอบ:
แยกความแตกต่างขนาน (ใช้หน่วยคำนวณพิเศษเพื่อทำงานต่อหน่วยเวลามากขึ้น) จากการทำงานพร้อมกัน (การจัดการการเข้าถึงทรัพยากรที่ใช้ร่วมกัน) สอนขนานแรกเพราะง่ายกว่าและช่วยสร้างความคิดที่ไม่ต่อเนื่อง
จาก "A Sophomoric ∗ บทนำสู่การแชร์หน่วยความจำและความพร้อมใช้งานร่วมกัน" โดย Dan Grossman (รุ่น 16 พฤศจิกายน 2013)
นอกเหนือไปจากคำตอบของ Nish ให้ฉันแนะนำหนังสือไซมอนมาร์โลว์ในการเขียนโปรแกรมแบบขนานและพร้อมกันใน Haskellหรือเขากวดวิชาสั้น พวกเขาตอบคำถามแรกของคุณจากมุมมองของ Haskell ดังนั้นพวกเขาจึงเหมาะสำหรับผู้อ่านที่ชอบทฤษฎีมากกว่า
การอ้างอิงจากที่นั่น:
ในหลาย ๆ ฟิลด์คำขนานและเกิดขึ้นพร้อมกันคือคำพ้องความหมาย ไม่ใช่ในการเขียนโปรแกรมซึ่งใช้อธิบายแนวคิดที่แตกต่างกันโดยพื้นฐาน
โปรแกรมแบบขนานเป็นโปรแกรมที่ใช้ฮาร์ดแวร์การคำนวณหลายหลาก (เช่นหลายแกนประมวลผล) เพื่อทำการคำนวณได้เร็วขึ้น ส่วนต่าง ๆ ของการคำนวณนั้นจะมอบให้กับหน่วยประมวลผลต่าง ๆ ที่ดำเนินการในเวลาเดียวกัน (เป็นแบบคู่ขนาน) ดังนั้นผลลัพธ์อาจถูกส่งเร็วกว่าการคำนวณแบบเรียงลำดับ
ในทางตรงกันข้ามการทำงานพร้อมกันเป็นเทคนิคการจัดทำโปรแกรมซึ่งมีหลายหัวข้อของการควบคุม โดยไม่คำนึงถึงหัวข้อของการควบคุมดำเนินการ "ในเวลาเดียวกัน"; นั่นคือผู้ใช้เห็นผลกระทบของพวกเขา interleaved ไม่ว่าพวกเขาจะทำงานจริงในเวลาเดียวกันหรือไม่เป็นรายละเอียดการใช้งาน; โปรแกรมที่ทำงานพร้อมกันสามารถดำเนินการกับตัวประมวลผลเดียวผ่านการประมวลผลแบบอินเตอร์ลีฟหรือบนตัวประมวลผลทางกายภาพหลายตัว
ฉันขอแนะนำให้อ่านส่วนที่เหลือในบทช่วยสอน (หน้า 4) แต่ให้ฉันพูดถึงส่วนที่เหลือของส่วนนี้เนื่องจากมันเชื่อมโยงกระบวนทัศน์การเขียนโปรแกรมทั้งสองเข้ากับลักษณะเชิงปริมาณและเชิงคุณภาพของโปรแกรมเช่นประสิทธิภาพแบบแยกส่วนและระดับ
ในขณะที่การเขียนโปรแกรมแบบขนานนั้นเกี่ยวข้องกับประสิทธิภาพเพียงอย่างเดียว แต่การเขียนโปรแกรมแบบพร้อมกันนั้นเกี่ยวข้องกับการสร้างโปรแกรมที่ต้องการโต้ตอบกับเอเจนต์ภายนอกหลายตัว (เช่นผู้ใช้เซิร์ฟเวอร์ฐานข้อมูลและไคลเอนต์ภายนอกบางตัว) การทำงานพร้อมกันช่วยให้โปรแกรมดังกล่าวเป็นแบบแยกส่วน; เธรดที่โต้ตอบกับผู้ใช้นั้นแตกต่างจากเธรดที่พูดกับฐานข้อมูล ในกรณีที่ไม่มีการทำงานพร้อมกันโปรแกรมดังกล่าวจะต้องเขียนด้วยลูปเหตุการณ์และการโทรกลับ - แน่นอนมักจะใช้ลูปเหตุการณ์และการโทรกลับแม้ว่าจะมีการทำงานพร้อมกันเพราะในหลายภาษามีราคาแพงเกินไปหรือยากเกินไป ใช้.
แนวคิดของ "เธรดการควบคุม" ไม่สมเหตุสมผลในโปรแกรมการทำงานอย่างหมดจดเนื่องจากไม่มีผลที่จะสังเกตและลำดับการประเมินผลไม่เกี่ยวข้อง ดังนั้นการทำงานพร้อมกันเป็นเทคนิคการสร้างรหัสที่มีประสิทธิผล ใน Haskell นั่นหมายถึงรหัสใน IO monad
ความแตกต่างที่เกี่ยวข้องอยู่ระหว่างโมเดลการโปรแกรมมิงแบบกำหนดแน่นอนและแบบ nondeterministic โมเดลการโปรแกรมมิงแบบกำหนดค่าคือหนึ่งในแต่ละโปรแกรมสามารถให้ผลลัพธ์เดียวเท่านั้นในขณะที่โมเดลการโปรแกรมมิงแบบกำหนดเองยอมรับโปรแกรมที่อาจมีผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับลักษณะของการดำเนินการบางอย่าง โมเดลการโปรแกรมมิงพร้อมกันนั้นจำเป็นต้องเป็น nondeterministic เพราะต้องโต้ตอบกับเอเจนต์ภายนอกที่ทำให้เกิดเหตุการณ์ในเวลาที่คาดเดาไม่ได้ Nondeterminism มีข้อเสียเปรียบบางประการอย่างไรก็ตาม: โปรแกรมกลายเป็นเรื่องยากที่จะทดสอบและให้เหตุผลอย่างมีนัยสำคัญ
สำหรับการเขียนโปรแกรมแบบขนานเราต้องการใช้โมเดลการเขียนโปรแกรมที่กำหนดขึ้นหากเป็นไปได้ เนื่องจากเป้าหมายเพียงเพื่อให้ได้คำตอบที่รวดเร็วยิ่งขึ้นเราจะไม่ทำให้โปรแกรมของเรายากขึ้นในการดีบักในกระบวนการ การเขียนโปรแกรมแบบกำหนดแน่นอนเป็นสิ่งที่ดีที่สุดของโลกทั้งสอง: การทดสอบการดีบักและการใช้เหตุผลสามารถทำได้ในโปรแกรมลำดับ แต่โปรแกรมจะทำงานได้เร็วขึ้นเมื่อมีการเพิ่มตัวประมวลผล แท้จริงแล้วตัวประมวลผลคอมพิวเตอร์ส่วนใหญ่ใช้ตัวขนานที่กำหนดขึ้นในรูปแบบของ pipelining และหลายหน่วยการเรียกใช้
ในขณะที่มันเป็นไปได้ที่จะทำการเขียนโปรแกรมแบบขนานโดยใช้การทำงานพร้อมกันซึ่งมักเป็นทางเลือกที่ไม่ดี ใน Haskell โมเดลการเขียนโปรแกรมแบบขนานนั้นถูกกำหนดไว้แล้ว อย่างไรก็ตามมันเป็นสิ่งสำคัญที่จะต้องทราบว่ารูปแบบการเขียนโปรแกรมที่กำหนดขึ้นไม่เพียงพอที่จะแสดงอัลกอริธึมแบบขนานทุกชนิด มีอัลกอริธึมที่ขึ้นอยู่กับลัทธิ nondeterminism ภายในโดยเฉพาะปัญหาที่เกี่ยวข้องกับการค้นหาพื้นที่การแก้ปัญหา ใน Haskell อัลกอริธึมของคลาสนี้สามารถใช้งานได้พร้อมกันโดยชัดแจ้งเท่านั้น
การเห็นพ้องและขนานในปัญหาที่พวกเขาแก้ไขและก่อให้เกิด แต่พวกเขาไม่ได้เป็นอิสระ
การดำเนินการสองภารกิจพร้อมกันหมายความว่าแต่ละขั้นตอนของภารกิจทั้งสองนั้นถูกดำเนินการในลักษณะอินเทอร์เลฟ หากคุณไม่สนใจความขนานคุณสามารถสันนิษฐานได้ว่ามีคำสั่งเพียงคำสั่งเดียวที่ดำเนินการในเวลาใดก็ได้ แต่คุณมี (ที่มีลำดับความสำคัญ) ไม่มีการรับประกันว่างานใดจะได้รับการดำเนินการในขั้นตอนถัดไป
สิ่งนี้มีประโยชน์ในบางเรื่อง:
ความท้าทายหลัก ๆ ได้แก่ :
การดำเนินการทั้งสองงานในแบบคู่ขนานหมายถึงว่างบจะดำเนินการในเวลาเดียวกัน สิ่งนี้มีประโยชน์สำหรับ:
ความท้าทายที่สำคัญ ได้แก่ :
ดูคำถามนี้เพื่อแยกความแตกต่างระหว่างการคำนวณแบบขนานและแบบกระจาย
คำตอบที่เงียบสงบเล็กน้อยอาจจะ ...
เห็นพ้องเป็นทรัพย์สินของวิธีการที่โปรแกรมที่เป็นลายลักษณ์อักษร หากโปรแกรมถูกเขียนโดยใช้สิ่งปลูกสร้างเช่น forks / joins, ล็อค, ธุรกรรม, การดำเนินการเปรียบเทียบและสลับอะตอมมิกและอื่น ๆ มันจะเกิดขึ้นพร้อมกัน
ขนานเป็นทรัพย์สินของวิธีการที่โปรแกรมรัน หากโปรแกรมดำเนินการกับหน่วยการคำนวณมากกว่าหนึ่งหน่วยพร้อมกันแสดงว่ามีการดำเนินการแบบขนาน
มีคำตอบมากมายในเรื่องนี้ แต่มันอาจทำให้สับสน ฉันชอบคิดแบบนี้และอาจช่วยได้:
การเขียนโปรแกรมพร้อมกันคือรหัสที่ไม่สนใจลำดับของการดำเนินการ Java เป็นภาษาที่ไม่ดีสำหรับการเขียนโปรแกรมพร้อมกัน แต่มีไลบรารีและกรอบงานที่จะช่วย JavaScript เป็นภาษาที่ยอดเยี่ยมสำหรับการเขียนโปรแกรมพร้อมกันและมักจะยากเมื่อคุณต้องการเขียนสิ่งที่ไม่พร้อมกัน (เช่นหากคุณต้องการบังคับให้ลำดับการดำเนินการ) การเขียนโปรแกรมพร้อมกันนั้นยอดเยี่ยมสำหรับการเขียนโปรแกรมเชิงเหตุการณ์ (ซึ่งลำดับการดำเนินการถูกกำหนดโดยผู้ฟังเหตุการณ์เช่นรหัสที่ทำงานในเบราว์เซอร์ของคุณซึ่งทำงานเมื่อคุณคลิกปุ่ม
ตัวอย่างจะรวมถึงการสร้างคำขอ HTTP นับร้อยรายการ ใน NodeJS ทางออกที่ง่ายที่สุดคือการเปิด 100 คำขอพร้อมกันด้วยวิธีการโทรกลับและเมื่อคำตอบกลับมาวิธีการจะดำเนินการในแต่ละครั้ง นั่นคือการเขียนโปรแกรมพร้อมกัน ใน Ruby โซลูชันที่ธรรมดาที่สุด (ธรรมดาที่สุด) คือการเปิดคำขอและจัดการการตอบสนองเปิดการร้องขอถัดไปและจัดการกับการตอบสนอง ฯลฯ สำหรับคำขอจำนวนมาก NodeJS นั้นทำได้ง่ายกว่าในเวลาที่เหมาะสมแม้ว่าคุณจะต้องเป็น ระมัดระวังเพื่อหลีกเลี่ยงการใช้เซิร์ฟเวอร์หรือเพิ่มการเชื่อมต่อขาออกของคุณให้สูงสุด คุณสามารถเขียน Ruby ด้วยวิธีที่เกิดขึ้นพร้อมกัน แต่ไม่ใช่การเขียนโค้ด Ruby ส่วนใหญ่และมันเจ็บเล็กน้อยที่จะทำ
การเขียนโปรแกรมแบบขนานเป็นรหัสที่สามารถเรียกใช้พร้อมกันในหลายเธรดหรือกระบวนการ สิ่งนี้ช่วยให้คุณสามารถปรับปรุงประสิทธิภาพโดยการเรียกใช้รหัสในซีพียูหลายตัว (มักจะรวมถึงเครื่องหลายเครื่องเช่นเดียวกับ Akka) เนื่องจาก NodeJS ไม่ใช่มัลติเธรดและไม่มีการประมวลผลแบบขนานคุณไม่ต้องกังวลเกี่ยวกับการเขียนรหัส threadsafe (และรหัส JavaScript ส่วนใหญ่ที่ฉันเห็นไม่ได้เป็น threadsafe) ใน Java แม้ว่าภาษาจะไม่ทำให้การโปรแกรมพร้อมกันเป็นรูปแบบปกติ แต่การเขียนโปรแกรมแบบขนานนั้นมีอยู่ในตัวเป็นอย่างมากและคุณมักจะต้องกังวลเกี่ยวกับความปลอดภัยของเธรด หากคุณกำลังเขียนเว็บไซต์ใน Java โดยทั่วไปสิ่งนี้จะถูกเรียกใช้ในคอนเทนเนอร์ที่เรียกใช้แต่ละคำขอในเธรดแยกต่างหากในหน่วยความจำเดียวกัน
สิ่งที่กล่าวมาข้างต้นขึ้นอยู่กับขอบเขตและขอบเขตที่คุณกำลังพูดถึง ฉันทำงานบนเว็บไซต์ รหัส Java ส่วนใหญ่ที่ฉันเห็นไม่ใช่การเขียนโปรแกรมพร้อมกัน แน่นอนว่าถ้าคุณซูมออกมากพอลำดับที่คำขอของลูกค้าเข้ามานั้นไม่สำคัญ แต่ถ้าคุณซูมเข้าไปไกลกว่านั้นลำดับที่สิ่งต่าง ๆ จะถูกดำเนินการนั้นถูกกำหนดโดยรหัส แต่รหัสนั้นถูกเขียนขึ้นเพื่อให้การร้องขอสามารถดำเนินการคู่ขนานกับวัตถุที่ใช้ร่วมกันจำนวนมากที่ต้องปลอดภัยต่อเธรด
ในขณะเดียวกันโค้ดจาวาสคริปต์ที่ฉันเห็นส่วนใหญ่จะเกิดขึ้นพร้อมกัน: มันถูกเขียนในลักษณะที่ลำดับการดำเนินการนั้นไม่สำคัญในหลาย ๆ ระดับ แต่จะไม่ถูกเขียนเพื่อรองรับการประมวลผลแบบขนานในหน่วยความจำที่แชร์ แน่นอนว่าคุณสามารถรันโค้ดเดียวกันแบบขนานข้ามกระบวนการหลายอย่าง แต่วัตถุไม่ได้ถูกแชร์ดังนั้นจึงไม่ใช่การเขียนโปรแกรมแบบขนานในแง่ที่มีความหมายใด ๆ
สำหรับการอ่านเพิ่มเติมฉันชอบภาพประกอบในคำตอบที่ดีที่สุดสำหรับคำถามนี้ที่นี่: https://www.quora.com/What-are-the-differences-between-parallel-concurrent-and-asynchronous-programming