แม้ว่าเธรดสามารถเพิ่มความเร็วในการเรียกใช้โค้ดได้จริงหรือไม่ ทุกชิ้นส่วนของรหัสสามารถทำได้โดยใช้หัวข้อเดียวหรือมีบางสิ่งที่มีอยู่ที่สามารถทำได้โดยใช้หลายกระทู้?
แม้ว่าเธรดสามารถเพิ่มความเร็วในการเรียกใช้โค้ดได้จริงหรือไม่ ทุกชิ้นส่วนของรหัสสามารถทำได้โดยใช้หัวข้อเดียวหรือมีบางสิ่งที่มีอยู่ที่สามารถทำได้โดยใช้หลายกระทู้?
คำตอบ:
ประการแรกเธรดไม่สามารถเร่งความเร็วในการเรียกใช้โค้ดได้ พวกเขาไม่ทำให้คอมพิวเตอร์ทำงานได้เร็วขึ้น สิ่งที่พวกเขาทำได้คือเพิ่มประสิทธิภาพของคอมพิวเตอร์โดยใช้เวลาที่เสียไป ในการประมวลผลบางประเภทการเพิ่มประสิทธิภาพนี้สามารถเพิ่มประสิทธิภาพและลดเวลาทำงาน
คำตอบง่ายๆคือใช่ คุณสามารถเขียนโค้ดใด ๆ เพื่อให้ทำงานบนเธรดเดี่ยว หลักฐาน: ระบบตัวประมวลผลเดียวอาจเรียกใช้คำแนะนำเชิงเส้นเท่านั้น การมีการประมวลผลหลายบรรทัดทำได้โดยการขัดจังหวะการประมวลผลระบบปฏิบัติการบันทึกสถานะของเธรดปัจจุบันและเริ่มต้นการทำงานใหม่
ซับซ้อนคำตอบคือ ... ที่ซับซ้อนมากขึ้น! เหตุผลที่โปรแกรมแบบมัลติเธรดอาจมีประสิทธิภาพมากกว่าโปรแกรมเชิงเส้นเนื่องจากฮาร์ดแวร์ "ปัญหา" CPU สามารถประมวลผลการคำนวณได้เร็วกว่าหน่วยความจำและที่เก็บข้อมูลอย่างหนัก IO ตัวอย่างเช่นคำสั่ง "เพิ่ม" ดำเนินการได้เร็วกว่า "ดึงข้อมูล" แคชและคำสั่งโปรแกรมเฉพาะที่ดึงมา (ไม่แน่ใจในคำศัพท์ที่แน่นอนที่นี่) สามารถต่อสู้เรื่องนี้ได้บ้าง แต่ปัญหาเรื่องความเร็วยังคงอยู่
การทำเกลียวเป็นวิธีในการต่อสู้กับความไม่ตรงกันนี้โดยใช้ CPU สำหรับคำสั่งที่ผูกกับ CPU ในขณะที่คำสั่งของ IO นั้นเสร็จสิ้นแล้ว แผนการดำเนินการเธรดโดยทั่วไปน่าจะเป็น: ดึงข้อมูลประมวลผลข้อมูลเขียนข้อมูล สมมติว่าการดึงข้อมูลและการเขียนใช้เวลา 3 รอบและการประมวลผลใช้เวลาเพียงครั้งเดียวเพื่อวัตถุประสงค์ในการอธิบาย คุณสามารถเห็นได้ว่าในขณะที่คอมพิวเตอร์กำลังอ่านหรือเขียนมันไม่ได้ทำอะไรเลย 2 รอบเลยละ? เห็นได้ชัดว่ามันขี้เกียจและเราจำเป็นต้องทุบแส้การเพิ่มประสิทธิภาพของเรา!
เราสามารถเขียนกระบวนการโดยใช้เธรดเพื่อใช้เวลาที่สูญเปล่านี้:
และอื่น ๆ เห็นได้ชัดว่านี่เป็นตัวอย่างที่มีการวางแผนมาบ้าง แต่คุณสามารถดูได้ว่าเทคนิคนี้สามารถใช้เวลาที่ต้องใช้เพื่อรอ IO ได้อย่างไร
โปรดทราบว่าการทำเกลียวดังที่แสดงด้านบนสามารถเพิ่มประสิทธิภาพได้เฉพาะกับกระบวนการที่เชื่อมโยงกับ IO อย่างมากเท่านั้น หากโปรแกรมกำลังคำนวณสิ่งต่าง ๆ ส่วนใหญ่จะไม่มี "หลุม" จำนวนมากที่เราสามารถทำงานได้มากขึ้นนอกจากนี้ยังมีค่าใช้จ่ายของคำสั่งต่าง ๆ เมื่อสลับไปมาระหว่างเธรด หากคุณใช้เธรดจำนวนมากเกินไปซีพียูจะใช้เวลาส่วนใหญ่ในการเปลี่ยนเวลาและไม่ได้แก้ปัญหาจริงๆ ซึ่งเรียกว่าการนวด
นั่นคือทั้งหมดที่ดีและดีสำหรับหน่วยประมวลผลหลักเดียว แต่โปรเซสเซอร์ที่ทันสมัยส่วนใหญ่มีสองแกนหรือมากกว่า เธรดยังคงมีวัตถุประสงค์เดียวกัน - เพื่อเพิ่มการใช้งาน CPU ให้สูงสุด แต่คราวนี้เรามีความสามารถในการเรียกใช้สองคำสั่งแยกกันในเวลาเดียวกัน สิ่งนี้สามารถลดเวลาการทำงานลงได้ด้วยปัจจัยที่มีหลายคอร์ให้ใช้งานเพราะคอมพิวเตอร์กำลังทำงานหลายอย่างพร้อมกันไม่ใช่การสลับบริบท
ด้วยหลายคอร์เธรดจัดเตรียมวิธีการแบ่งงานระหว่างสองคอร์ ข้างต้นยังคงใช้สำหรับแต่ละแกนหลักแม้ว่า; โปรแกรมที่รันประสิทธิภาพสูงสุดด้วยสองเธรดบนหนึ่งคอร์ส่วนใหญ่จะทำงานที่ประสิทธิภาพสูงสุดโดยมีเธรดประมาณสี่เธรดบนสองคอร์ (วัดประสิทธิภาพได้ที่นี่ด้วยการประมวลผลคำสั่ง NOP ขั้นต่ำ)
ปัญหาเกี่ยวกับการรันเธรดบนหลายคอร์ (เมื่อเทียบกับคอร์แกนเดี่ยว) โดยทั่วไปจะได้รับการดูแลโดยฮาร์ดแวร์ ซีพียูจะต้องแน่ใจว่าล็อคตำแหน่งหน่วยความจำที่เหมาะสมก่อนที่จะอ่าน / เขียน (ฉันอ่านแล้วว่าใช้หน่วยความจำแฟลกบิตพิเศษสำหรับสิ่งนี้ แต่สามารถทำได้หลายวิธี) ในฐานะโปรแกรมเมอร์ที่มีภาษาระดับสูงกว่าคุณไม่ต้องกังวลอะไรอีกแล้วในสองคอร์ในขณะที่คุณ จะต้องมีด้วย
TL; DR:เธรดสามารถแบ่งการทำงานเพื่อให้คอมพิวเตอร์สามารถประมวลผลงานหลายอย่างแบบอะซิงโครนัส สิ่งนี้ทำให้คอมพิวเตอร์สามารถทำงานได้อย่างมีประสิทธิภาพสูงสุดโดยใช้เวลาในการประมวลผลทั้งหมดที่มีอยู่แทนที่จะล็อกเมื่อกระบวนการกำลังรอทรัพยากร
หลายเธรดสามารถทำสิ่งใดที่เธรดเดี่ยวไม่สามารถทำได้?
ไม่มีอะไร
ร่างหลักฐานง่าย ๆ :
อย่างไรก็ตามโปรดทราบว่ามีข้อสันนิษฐานขนาดใหญ่ซ่อนอยู่ในนั้นนั่นคือภาษาที่ใช้ภายในเธรดเดียวคือทัวริงสมบูรณ์
ดังนั้นคำถามที่น่าสนใจมากขึ้นจะเป็น: "สามารถเพิ่มเพียงแบบมัลติเธรดให้เป็นภาษาที่ไม่ใช่ทัวริงสมบูรณ์ทำให้มันทัวริงสมบูรณ์?" และฉันเชื่อว่าคำตอบคือ "ใช่"
มาฟังภาษาฟังก์ชั่นรวมกัน [สำหรับผู้ที่ไม่คุ้นเคย: เหมือนกับการเขียนโปรแกรมฟังก์ชั่นคือการเขียนโปรแกรมด้วยฟังก์ชั่นการเขียนโปรแกรมฟังก์ชั่นรวมคือการเขียนโปรแกรมด้วยฟังก์ชั่นรวม]
ภาษาที่ใช้งานได้ทั้งหมดไม่ชัดเจนทัวริง: คุณไม่สามารถเขียนวนวนไม่สิ้นสุดใน TFPL (อันที่จริงคำจำกัดความของ "รวม") แต่คุณสามารถทำได้ในโปรแกรมทัวริงดังนั้นอย่างน้อยหนึ่งโปรแกรมที่ ไม่สามารถเขียนใน TFPL แต่สามารถเป็น UTM ได้ดังนั้น TFPL จึงมีประสิทธิภาพในการคำนวณน้อยกว่า UTM
อย่างไรก็ตามทันทีที่คุณเพิ่มเธรดลงใน TFPL คุณจะได้รับการวนซ้ำไม่สิ้นสุด: ทำแต่ละลูปซ้ำในแต่ละเธรดใหม่ แต่ละเธรดแต่ละรายการจะส่งคืนผลลัพธ์เสมอดังนั้นจึงเป็นผลรวม แต่ทุกเธรดจะวางไข่เธรดใหม่ที่เรียกใช้การทำซ้ำครั้งถัดไปนั่นคือ infinitum โฆษณา
ฉันคิดว่าภาษานี้จะทัวริงสมบูรณ์
อย่างน้อยที่สุดก็ตอบคำถามต้นกำเนิด:
หลายเธรดสามารถทำสิ่งใดที่เธรดเดี่ยวไม่สามารถทำได้?
หากคุณมีภาษาที่ไม่สามารถทำลูปอนันต์, แล้วแบบมัลติเธรดช่วยให้คุณทำลูปไม่มีที่สิ้นสุด
หมายเหตุแน่นอนว่าการวางไข่เธรดเป็นผลข้างเคียงและทำให้ภาษาที่ขยายของเราไม่เพียง แต่ไม่รวมอีกต่อไป แต่ยังไม่สามารถใช้งานได้อีกต่อไป
ในทางทฤษฎีทุกสิ่งที่โปรแกรมแบบมัลติเธรดสามารถทำได้ด้วยโปรแกรมแบบเธรดเดียวเช่นกันเพียงช้าลง
ในทางปฏิบัติความแตกต่างของความเร็วอาจมีขนาดใหญ่มากจนไม่มีวิธีที่จะสามารถใช้โปรแกรมแบบเธรดเดี่ยวสำหรับงานได้ เช่นถ้าคุณมีงานการประมวลผลแบตช์ที่ทำงานอยู่ทุกคืนและใช้เวลานานกว่า 24 ชั่วโมงในการทำเธรดเดียวคุณไม่มีตัวเลือกอื่นนอกจากการทำแบบมัลติเธรด (ในทางปฏิบัติเกณฑ์อาจน้อยกว่า: บ่อยครั้งที่งานอัปเดตดังกล่าวจะต้องเสร็จสิ้นในช่วงเช้าก่อนที่ผู้ใช้จะเริ่มใช้ระบบอีกครั้งนอกจากนี้งานอื่น ๆ อาจขึ้นอยู่กับพวกเขาซึ่งจะต้องเสร็จในคืนเดียวกันด้วย เวลาใช้งานที่ว่างอาจน้อยเพียงไม่กี่ชั่วโมง / นาที)
การคำนวณการทำงานกับหลายเธรดเป็นรูปแบบของการประมวลผลแบบกระจาย คุณกำลังกระจายงานผ่านหลายกระทู้ อีกตัวอย่างหนึ่งของการประมวลผลแบบกระจาย (ใช้คอมพิวเตอร์หลายเครื่องแทนที่จะเป็นหลายเธรด) คือสกรีนเซฟเวอร์ SETI: การกระทืบว่าข้อมูลการวัดจำนวนมากในโปรเซสเซอร์เดียวจะใช้เวลานานมากและนักวิจัยต้องการเห็นผลลัพธ์ก่อนเกษียณ ;-) ไม่มีงบประมาณในการเช่าซูเปอร์คอมพิวเตอร์มานานดังนั้นพวกเขาจึงกระจายงานไปยังพีซีในครัวเรือนหลายล้านเครื่องเพื่อให้ถูก
แม้ว่าเธรดดูเหมือนจะเป็นขั้นตอนเล็ก ๆ จากการคำนวณตามลำดับ แต่จริงๆแล้วเธรดเหล่านั้นเป็นขั้นตอนที่ยิ่งใหญ่ พวกเขาทิ้งคุณสมบัติที่สำคัญที่สุดและน่าสนใจของการคำนวณตามลำดับ: ความเข้าใจความสามารถในการคาดการณ์และระดับ เธรดซึ่งเป็นแบบจำลองของการคำนวณเป็น nondeterministic ที่ดุร้ายและงานของโปรแกรมเมอร์กลายเป็นหนึ่งในการตัดแต่งที่ nondeterminism
- ปัญหาเกี่ยวกับเธรด (www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf)
ในขณะที่มีข้อได้เปรียบด้านประสิทธิภาพบางประการที่สามารถทำได้โดยใช้เธรดซึ่งคุณสามารถแจกจ่ายงานข้ามหลายคอร์ได้ แต่พวกเขามักจะมีราคาที่ดี
ข้อเสียอย่างหนึ่งของการใช้เธรดที่ไม่ได้กล่าวถึงที่นี่คือการสูญเสียการแบ่งส่วนทรัพยากรที่คุณได้รับด้วยช่องว่างกระบวนการเธรดเดี่ยว ตัวอย่างเช่นสมมติว่าคุณพบกรณีของ segfault ในบางกรณีมีความเป็นไปได้ที่จะกู้คืนจากสิ่งนี้ในแอพพลิเคชั่นแบบหลายขั้นตอนโดยที่คุณสามารถปล่อยให้เด็กที่มีความผิดพลาดตายและเกิดใหม่ได้ นี่เป็นกรณีในแบ็กเอนด์ prefork ของ Apache เมื่ออินสแตนซ์ httpd หนึ่งรายการหยุดทำงานกรณีที่แย่กว่านั้นคือคำขอ HTTP เฉพาะอาจถูกดร็อปสำหรับกระบวนการนั้น แต่ Apache จะวางลูกใหม่และมักจะร้องขอหากเพียงแค่ส่งใหม่และรับบริการ ผลลัพธ์ที่ได้คือ Apache โดยรวมไม่ได้ถูกลบออกด้วยเธรดที่ผิดพลาด
สิ่งที่ต้องพิจารณาในสถานการณ์นี้คือหน่วยความจำรั่ว มีบางกรณีที่คุณสามารถจัดการเธรดที่ล้มเหลวได้อย่างงดงาม (บน UNIX, การกู้คืนจากสัญญาณบางอย่าง - แม้ segfault / fpviolation - เป็นไปได้) แต่ในกรณีนั้นคุณอาจรั่วหน่วยความจำทั้งหมดที่จัดสรรโดยเธรดนั้น (malloc, new, etc. ) ดังนั้นในขณะที่กระบวนการของคุณอาจเปิดอยู่มันจะรั่วไหลหน่วยความจำมากขึ้นเรื่อย ๆ เมื่อเกิดข้อผิดพลาด / การกู้คืนแต่ละครั้ง อีกครั้งมีวิธีการบางอย่างเพื่อลดขนาดนี้เช่นการใช้พูลหน่วยความจำของ Apache แต่นี่ยังไม่ป้องกันหน่วยความจำที่อาจถูกจัดสรรโดยบุคคลที่สาม libs ที่อาจใช้เธรด
และในขณะที่บางคนชี้ให้เห็นการทำความเข้าใจกับการซิงโครไนซ์ดั้งเดิมอาจเป็นสิ่งที่ยากที่สุดที่จะทำให้ถูกต้อง ปัญหานี้ด้วยตัวเอง - แค่รับตรรกะทั่วไปที่ถูกต้องสำหรับรหัสของคุณทั้งหมด - อาจปวดหัวมาก การหยุดชะงักลึกลับมักเกิดขึ้นในช่วงเวลาที่แปลกประหลาดและบางครั้งก็ไม่ได้จนกว่าโปรแกรมของคุณจะทำงานในการผลิตซึ่งทำให้การดีบักยากขึ้นทั้งหมด เพิ่มความจริงที่ว่าการซิงโครไนซ์แบบดั้งเดิมมักจะแตกต่างกันอย่างมากกับแพลตฟอร์ม (Windows กับ POSIX) และการดีบักอาจเป็นเรื่องยากมากขึ้นรวมถึงความเป็นไปได้สำหรับสภาพการแข่งขันในเวลาใดก็ได้ (เริ่มต้น / เริ่มต้นเริ่มต้นใช้งานและปิด) การเขียนโปรแกรมด้วยเธรดมีความเมตตาเล็กน้อยสำหรับผู้เริ่มต้น และแม้กระทั่งสำหรับผู้เชี่ยวชาญ ยังคงมีความเมตตาเพียงเล็กน้อยเพราะความรู้ในการทำเกลียวตัวเองไม่ได้ลดความซับซ้อนลงโดยทั่วไป แต่ละครั้งของโค้ดเธรดแต่ละครั้งดูเหมือนจะเพิ่มความซับซ้อนโดยรวมของโปรแกรมเป็นอย่างมากรวมทั้งเพิ่มความน่าจะเป็นสำหรับการหยุดชะงักที่ซ่อนอยู่หรือสภาพการแข่งขันที่แปลกไปยังพื้นผิวได้ตลอดเวลา มันอาจเป็นเรื่องยากมากที่จะเขียนกรณีทดสอบเพื่อค้นหาสิ่งเหล่านี้
นี่คือเหตุผลที่บางโครงการเช่น Apache และ PostgreSQL นั้นใช้กระบวนการเป็นส่วนใหญ่ PostgreSQL รันทุก ๆ แบ็กเอนด์เธรดในกระบวนการแยกกัน แน่นอนว่านี่ยังไม่ได้ช่วยบรรเทาปัญหาการซิงโครไนซ์และเงื่อนไขการแข่งขัน แต่มันเพิ่มการป้องกันเล็กน้อยและในบางวิธีทำให้สิ่งต่าง ๆ ง่ายขึ้น
กระบวนการหลายกระบวนการแต่ละการรันการประมวลผลเธรดเดียวสามารถทำได้ดีกว่าการประมวลผลหลายเธรดในกระบวนการเดียว และด้วยการมาถึงของรหัสเพียร์ทูเพียร์ใหม่เช่น AMQP (RabbitMQ, Qpid ฯลฯ ) และ ZeroMQ มันง่ายกว่ามากในการแยกเธรดในพื้นที่กระบวนการที่แตกต่างกันและแม้แต่เครื่องจักรและเครือข่ายทำให้สิ่งต่าง ๆ ง่ายขึ้นอย่างมาก แต่ถึงกระนั้นก็ไม่ใช่กระสุนเงิน ยังคงมีความซับซ้อนในการจัดการกับ คุณเพียงแค่ย้ายตัวแปรบางตัวจากพื้นที่กระบวนการไปยังเครือข่าย
บรรทัดล่างคือการตัดสินใจที่จะเข้าสู่โดเมนของกระทู้ไม่เบา เมื่อคุณก้าวเข้าสู่ดินแดนนั้นแทบจะในทันทีทันใดทุกอย่างก็จะซับซ้อนมากขึ้นและปัญหาใหม่ ๆ เข้ามาในชีวิตของคุณ มันอาจสนุกและเท่ห์ แต่ก็เหมือนพลังงานนิวเคลียร์ - เมื่อสิ่งต่าง ๆ ผิดพลาดพวกเขาสามารถไปได้ไม่ดีและรวดเร็ว ฉันจำได้ว่าได้เข้าเรียนในการฝึกอบรมเรื่องวิกฤติเมื่อหลายปีก่อนและพวกเขาแสดงรูปภาพของนักวิทยาศาสตร์บางคนที่ลอสอาลามอสซึ่งเล่นกับพลูโทเนียมในห้องทดลองในสงครามโลกครั้งที่สอง หลายคนใช้มาตรการป้องกันเล็กน้อยหรือไม่มีเลยกับเหตุการณ์ที่มีการเปิดรับแสงและในพริบตา - ในแฟลชที่สว่างไสวและไม่เจ็บปวดเพียงครั้งเดียว วันต่อมาพวกเขาก็ตาย Richard Feynman ต่อมาเรียกสิ่งนี้ว่า " กระตุ้นหางของมังกร(อย่างน้อยก็สำหรับฉันแล้ว) ดูเหมือนว่าจะไม่มีพิษภัยในตอนแรกและเมื่อถึงเวลาที่คุณกัดคุณก็จะเกาหัวของคุณในสิ่งที่เกิดขึ้นอย่างรวดเร็ว แต่อย่างน้อยก็ชนะ ไม่ต้องฆ่าคุณ
ก่อนอื่นแอปพลิเคชันเธรดเดียวจะไม่ใช้ประโยชน์จาก CPU แบบมัลติคอร์หรือไฮเปอร์เธรด แต่ถึงแม้จะอยู่บนแกนเดียว CPU แบบเธรดเดี่ยวที่ทำมัลติเธรดก็มีข้อดี
พิจารณาทางเลือกและสิ่งที่ทำให้คุณมีความสุข สมมติว่าคุณมีหลายงานที่ต้องทำงานพร้อมกัน ตัวอย่างเช่นคุณต้องสื่อสารกับระบบที่แตกต่างกันสองระบบ คุณจะทำเช่นนี้ได้อย่างไรโดยไม่ต้องใช้มัลติเธรด คุณอาจจะสร้างตัวกำหนดตารางเวลาของคุณเองและปล่อยให้มันเรียกใช้งานที่แตกต่างที่ต้องดำเนินการ ซึ่งหมายความว่าคุณต้องแบ่งงานของคุณออกเป็นส่วน ๆ คุณอาจต้องปฏิบัติตามข้อ จำกัด แบบเรียลไทม์คุณต้องแน่ใจว่าชิ้นส่วนของคุณไม่ใช้เวลามากเกินไป มิฉะนั้นตัวจับเวลาจะหมดอายุในงานอื่น ๆ สิ่งนี้ทำให้การแบ่งงานยากขึ้น ยิ่งคุณต้องจัดการตัวเองมากเท่าไรคุณก็ยิ่งต้องแยกตัวออกมากขึ้นและตัวกำหนดตารางเวลาของคุณก็จะซับซ้อนมากขึ้นตามข้อ จำกัด ทั้งหมด
เมื่อคุณมีหลายเธรดอายุการใช้งานอาจกลายเป็นเรื่องง่ายขึ้น ตัวกำหนดตารางเวลาแบบจองล่วงหน้าสามารถหยุดเธรดได้ตลอดเวลารักษาสถานะและเริ่มใหม่อีกครั้ง มันจะรีสตาร์ทเมื่อเธรดของคุณได้รับการเปิด ข้อดี: ความซับซ้อนของการเขียนตัวกำหนดตารางเวลาได้ดำเนินการแล้วสำหรับคุณและคุณไม่จำเป็นต้องแยกงานของคุณออก นอกจากนี้ตัวกำหนดตารางเวลายังมีความสามารถในการจัดการกระบวนการ / เธรดที่ตัวคุณเองไม่ได้ตระหนักถึง และเมื่อเธรดไม่ต้องการทำสิ่งใด (กำลังรอเหตุการณ์บางอย่าง) จะไม่ใช้รอบ CPU นี่ไม่ใช่เรื่องง่ายที่จะทำให้สำเร็จเมื่อคุณสร้างตัวกำหนดตารางเวลาแบบเธรดเดี่ยวของคุณลง (การทำให้บางอย่างเข้าสู่โหมดสลีปไม่ใช่เรื่องยาก แต่มันตื่นขึ้นมาอย่างไร)
ข้อเสียของการพัฒนาแบบมัลติเธรดคือคุณต้องเข้าใจเกี่ยวกับปัญหาการเกิดพร้อมกันกลยุทธ์การล็อคและอื่น ๆ การพัฒนาโค้ดหลายเธรดที่ปราศจากข้อผิดพลาดนั้นค่อนข้างยาก และการแก้ไขข้อบกพร่องอาจยิ่งยากขึ้น
มีบางสิ่งที่มีอยู่ที่สามารถทำได้โดยใช้หลายเธรดเท่านั้น?
ใช่. คุณไม่สามารถเรียกใช้รหัสบน CPU หลายแกนหรือแกนประมวลผล CPU ด้วยเธรดเดียว
หากไม่มีหลาย CPU / แกนประมวลผลเธรดยังสามารถทำให้โค้ดที่ทำงานแบบขนานนั้นง่ายขึ้นเช่นการจัดการไคลเอ็นต์บนเซิร์ฟเวอร์ - แต่คุณสามารถทำสิ่งเดียวกันได้โดยไม่ต้องใช้เธรด
หัวข้อไม่เพียง แต่เกี่ยวกับความเร็ว แต่เกี่ยวกับการทำงานพร้อมกัน
หากคุณไม่มีแบทช์แอปพลิเคชันตามที่ @Peter แนะนำ แต่แทนที่จะเป็นชุดเครื่องมือ GUI เช่น WPF คุณจะโต้ตอบกับผู้ใช้และตรรกะทางธุรกิจด้วยเธรดเดียวได้อย่างไร
นอกจากนี้สมมติว่าคุณกำลังสร้างเว็บเซิร์ฟเวอร์ คุณจะให้บริการผู้ใช้มากกว่าหนึ่งคนพร้อมกันเพียงหนึ่งเธรดได้อย่างไร (หากไม่มีกระบวนการอื่น)
มีหลายสถานการณ์ที่เพียงแค่เธรดเดียวยังไม่เพียงพอ นั่นเป็นเหตุผลที่ความก้าวหน้าล่าสุดเช่นโปรเซสเซอร์ Intel MIC ที่มีมากกว่า 50 คอร์และเธรดหลายร้อยรายการเกิดขึ้น
ใช่การเขียนโปรแกรมแบบขนานและพร้อมกันนั้นยาก แต่จำเป็น
Multi-Threading สามารถให้อินเตอร์เฟส GUI ยังคงตอบสนองได้ในระหว่างการดำเนินการที่ยาวนาน หากไม่มีหลายเธรดผู้ใช้จะต้องดูรูปแบบที่ถูกล็อคไว้ในขณะที่กระบวนการที่ยาวกำลังทำงานอยู่
รหัสแบบมัลติเธรดสามารถหยุดการทำงานของลอจิกโปรแกรมและเข้าถึงข้อมูลเก่าในลักษณะที่เธรดเดี่ยวไม่สามารถทำได้
เธรดสามารถใช้บั๊กที่คลุมเครือจากบางสิ่งที่โปรแกรมเมอร์โดยเฉลี่ยคาดว่าจะทำการดีบั๊กและย้ายไปยังอาณาจักรที่มีการบอกเล่าเรื่องราวของโชคที่จำเป็นในการจับบั๊กเดียวกันกับกางเกงของมันลงเมื่อโปรแกรมเมอร์เตือนเกิดขึ้นมามอง ช่วงเวลาที่เหมาะสม
แอพที่เกี่ยวข้องกับการบล็อก IO ที่ยังต้องตอบสนองต่ออินพุตอื่น ๆ (GUI หรือการเชื่อมต่ออื่น ๆ ) ไม่สามารถทำได้แบบเธรดเดียว
การเพิ่มวิธีการตรวจสอบใน IO lib เพื่อดูว่าสามารถอ่านได้มากน้อยเพียงใดโดยไม่มีการปิดกั้นสามารถช่วยได้ แต่มีไลบรารีไม่กี่แห่งที่รับประกันเรื่องนี้อย่างเต็มที่
มีคำตอบที่ดีมากมาย แต่ฉันไม่แน่ใจว่าวลีใดเป็นอย่างที่ฉันต้องการ - บางทีนี่อาจเป็นวิธีที่แตกต่างในการดู:
เธรดเป็นเพียงการทำให้โปรแกรมง่ายขึ้นเช่น Objects หรือ Actors หรือสำหรับลูป (ใช่สิ่งที่คุณใช้กับลูปที่คุณสามารถนำไปใช้กับ if / goto)
หากไม่มีเธรดคุณเพียงแค่สร้างเอ็นจิ้นรัฐ ฉันต้องทำสิ่งนี้หลายครั้ง (ครั้งแรกที่ฉันทำฉันไม่เคยได้ยินเลย - ทำคำสั่งสวิตช์ขนาดใหญ่ที่ควบคุมโดยตัวแปร "สถานะ") เครื่องจักรของรัฐยังคงเป็นเรื่องปกติ แต่ก็น่ารำคาญ เมื่อใช้เธรดชิ้นส่วนขนาดใหญ่ของสำเร็จรูปก็หายไป
พวกเขายังทำให้ภาษาง่ายขึ้นสำหรับการแบ่งการดำเนินการรันไทม์ลงในกลุ่มที่เป็นมิตรกับ CPU หลายตัว (ฉันเชื่อว่านักแสดง)
Java มีเธรด "สีเขียว" บนระบบที่ระบบปฏิบัติการไม่สนับสนุนการเธรดใด ๆ ในกรณีนี้มันง่ายกว่าที่จะเห็นว่าไม่มีอะไรมากไปกว่าการเขียนโปรแกรมเชิงนามธรรม
ระบบปฏิบัติการใช้แนวคิดการแบ่งส่วนเวลาที่แต่ละเธรดได้รับถึงเวลาที่ต้องรันจากนั้นถูกยึดเอาไว้ วิธีการเช่นนี้สามารถแทนที่เธรดได้เหมือนตอนนี้ แต่การเขียนตัวกำหนดตารางเวลาของคุณเองในทุกแอปพลิเคชันจะมีค่าใช้จ่ายมากเกินไป ยิ่งกว่านั้นคุณต้องทำงานกับอุปกรณ์ I / O และอื่น ๆ และต้องการการสนับสนุนจากด้านฮาร์ดแวร์เพื่อให้คุณสามารถเริ่มการขัดจังหวะเพื่อเรียกใช้ตัวกำหนดตารางเวลาของคุณ โดยทั่วไปคุณจะต้องเขียนระบบปฏิบัติการใหม่ทุกครั้ง
โดยทั่วไปเธรดสามารถปรับปรุงประสิทธิภาพในกรณีที่เธรดรอ I / O หรือกำลังหลับ นอกจากนี้ยังช่วยให้คุณสร้างอินเทอร์เฟซที่ตอบสนองและอนุญาตให้กระบวนการหยุดในขณะที่คุณทำงานที่ยาวนาน และการทำเกลียวยังช่วยปรับปรุงสิ่งต่างๆบน CPU ที่มีมัลติคอร์ที่แท้จริง
ขั้นแรกเธรดสามารถทำสองสิ่งหรือมากกว่าในเวลาเดียวกัน (ถ้าคุณมีมากกว่าหนึ่งคอร์) ในขณะที่คุณสามารถทำได้ด้วยหลายกระบวนการ แต่บางงานก็ไม่กระจายไปตามหลาย ๆ กระบวนการอย่างดี
นอกจากนี้งานบางอย่างมีช่องว่างในงานที่คุณไม่สามารถหลีกเลี่ยงได้ง่าย ตัวอย่างเช่นการอ่านข้อมูลจากไฟล์บนดิสก์เป็นเรื่องยากและกระบวนการของคุณก็ต้องทำอย่างอื่นในเวลาเดียวกัน หากงานของคุณจำเป็นต้องอ่านข้อมูลจำนวนมากจากดิสก์กระบวนการของคุณจะใช้เวลานานในการรอดิสก์ไม่ว่าคุณจะทำอะไร
ประการที่สองเธรดสามารถอนุญาตให้คุณหลีกเลี่ยงการเพิ่มประสิทธิภาพโค้ดของคุณในปริมาณมากซึ่งไม่สำคัญต่อประสิทธิภาพ หากคุณมีเพียงเธรดเดียวทุกส่วนของโค้ดจะมีประสิทธิภาพที่สำคัญ ถ้ามันบล็อกคุณจะจม - ไม่มีงานที่จะทำโดยกระบวนการนั้นสามารถทำให้ก้าวหน้าไปข้างหน้า ด้วยเธรดบล็อกจะมีผลกับเธรดนั้นและเธรดอื่นเท่านั้นที่สามารถเข้ามาและทำงานกับงานที่ต้องทำโดยกระบวนการนั้น
ตัวอย่างที่ดีคือรหัสการจัดการข้อผิดพลาดที่ดำเนินการไม่บ่อยนัก สมมติว่างานพบข้อผิดพลาดไม่บ่อยนักและรหัสเพื่อจัดการกับข้อผิดพลาดนั้นจำเป็นต้องเพจลงในหน่วยความจำ หากดิสก์ไม่ว่างและกระบวนการมีเธรดเดียวเท่านั้นไม่สามารถดำเนินการไปข้างหน้าจนกว่าจะสามารถโหลดรหัสเพื่อจัดการข้อผิดพลาดนั้นลงในหน่วยความจำได้ สิ่งนี้อาจทำให้เกิดการตอบสนองต่อเสียงระเบิด
อีกตัวอย่างหนึ่งคือถ้าคุณอาจไม่ค่อยต้องค้นหาฐานข้อมูล หากคุณรอให้ฐานข้อมูลตอบกลับรหัสของคุณจะล่าช้าอย่างมาก แต่คุณไม่ต้องการไปที่ปัญหาในการสร้างโค้ดทั้งหมดแบบอะซิงโครนัสเพราะมันยากมากที่คุณต้องทำการค้นหาเหล่านี้ ด้วยการใช้เธรดเพื่อทำงานนี้คุณจะได้รับสิ่งที่ดีที่สุดทั้งสองโลก เธรดที่จะทำงานนี้ทำให้ประสิทธิภาพไม่สำคัญเท่าที่ควร