ความแตกต่างระหว่างการใช้เธรดใหม่และการใช้เธรดจากเธรดพูลคืออะไร? มีประโยชน์ด้านประสิทธิภาพอะไรบ้างและเหตุใดฉันจึงควรพิจารณาใช้เธรดจากพูลแทนที่จะใช้เธรดที่ฉันสร้างขึ้นอย่างชัดเจน ฉันกำลังคิดถึง. NET ที่นี่โดยเฉพาะ แต่ตัวอย่างทั่วไปก็ใช้ได้
ความแตกต่างระหว่างการใช้เธรดใหม่และการใช้เธรดจากเธรดพูลคืออะไร? มีประโยชน์ด้านประสิทธิภาพอะไรบ้างและเหตุใดฉันจึงควรพิจารณาใช้เธรดจากพูลแทนที่จะใช้เธรดที่ฉันสร้างขึ้นอย่างชัดเจน ฉันกำลังคิดถึง. NET ที่นี่โดยเฉพาะ แต่ตัวอย่างทั่วไปก็ใช้ได้
คำตอบ:
เธรดพูลจะให้ประโยชน์สำหรับการดำเนินการบ่อยและค่อนข้างสั้นโดย
การควบคุมอัตราการสร้างเธรดเมื่อมีคำขอรายการงานใหม่จำนวนมาก (ฉันเชื่อว่านี่เป็นเพียงใน. NET 3.5)
หากคุณจัดคิวงานพูลเธรด 100 เธรดจะใช้เฉพาะเธรดจำนวนมากเท่าที่สร้างไว้แล้วเพื่อรองรับการร้องขอเหล่านี้ (เช่น 10 เช่น) เธรดพูลจะทำการตรวจสอบบ่อยครั้ง (ฉันเชื่อว่าทุกๆ 500ms ใน 3.5 SP1) และหากมีงานที่อยู่ในคิวก็จะสร้างเธรดใหม่หนึ่งชุด หากงานของคุณรวดเร็วจำนวนเธรดใหม่จะน้อยและการนำเธรด 10 หรือมากกว่านั้นกลับมาใช้ใหม่สำหรับงานสั้น ๆ จะเร็วกว่าการสร้างเธรด 100 เธรดขึ้นข้างหน้า
หากปริมาณงานของคุณมีคำขอพูลเธรดจำนวนมากเข้ามาอย่างต่อเนื่องเธรดพูลจะปรับตัวเองให้เข้ากับปริมาณงานของคุณโดยการสร้างเธรดเพิ่มเติมในพูลตามกระบวนการข้างต้นเพื่อให้มีเธรดจำนวนมากขึ้นเพื่อประมวลผลคำขอ
ตรวจสอบที่นี่สำหรับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับการทำงานของเธรดพูลภายใต้ประทุน
การสร้างเธรดใหม่ด้วยตัวคุณเองจะเหมาะสมกว่าหากงานกำลังจะดำเนินไปค่อนข้างนาน (อาจใช้เวลาประมาณหนึ่งหรือสองวินาที แต่ขึ้นอยู่กับสถานการณ์เฉพาะ)
@Krzysztof - เธรดพูลเธรดคือเธรดพื้นหลังที่จะหยุดเมื่อเธรดหลักสิ้นสุดลง เธรดที่สร้างขึ้นด้วยตนเองจะอยู่เบื้องหน้าตามค่าเริ่มต้น (จะทำงานต่อไปหลังจากเธรดหลักสิ้นสุดลง) แต่สามารถตั้งค่าเป็นพื้นหลังก่อนที่จะเรียกเริ่มบนเธรดเหล่านั้น
เธรดพูลที่มีการจัดการ. NET: -
มีการใช้เธรดพูลอื่น ๆ ที่อาจเหมาะสมกว่าสำหรับการดำเนินการที่รันเป็นเวลานาน
โดยเฉพาะใช้เธรดพูลเพื่อป้องกันไม่ให้แอปของคุณสร้างเธรดมากเกินไป คุณลักษณะที่สำคัญที่สุดของเธรดพูลคือคิวงาน นั่นคือเมื่อเครื่องของคุณมีงานยุ่งเพียงพอเธรดพูลจะจัดคิวคำขอแทนที่จะสร้างเธรดเพิ่มเติมทันที
ดังนั้นหากคุณจะสร้างเธรดขนาดเล็กจำนวน จำกัด ให้สร้างเธรดด้วยตัวคุณเอง หากคุณไม่สามารถระบุล่วงหน้าได้ว่าจะสร้างเธรดจำนวนเท่าใด (เช่นสร้างขึ้นเพื่อตอบสนองต่อ IO ที่เข้ามา) และงานของพวกเขาจะมีอายุสั้นให้ใช้เธรดพูล หากคุณไม่ทราบว่ามีจำนวนเท่าใด แต่งานของพวกเขาจะใช้งานได้ยาวนานไม่มีอะไรในแพลตฟอร์มที่จะช่วยคุณได้ แต่คุณอาจสามารถค้นหาการใช้งานเธรดพูลอื่นที่เหมาะสมได้
ด้วย
new Thread().Start()
วางไข่เธรด Foreground ที่จะไม่ตายหากคุณปิดโปรแกรมของคุณ เธรด ThreadPool คือเธรดพื้นหลังที่ตายเมื่อคุณปิดแอพ
ฉันอยากรู้อยากเห็นเกี่ยวกับการใช้ทรัพยากรสัมพัทธ์สำหรับสิ่งเหล่านี้และและใช้เกณฑ์มาตรฐานในแล็ปท็อป Intel i5 แบบดูอัลคอร์ปี 2012 ของฉันโดยใช้. net 4.0 release build บน windows 8 Thread Pools ใช้เวลาโดยเฉลี่ย 0.035ms ในการเริ่มต้นโดยที่ Threads ใช้เวลาเฉลี่ย 5.06 นางสาว. กล่าวอีกนัยหนึ่งเธรดในพูลเริ่มเร็วขึ้นประมาณ 300 เท่าสำหรับเธรดอายุสั้นจำนวนมาก อย่างน้อยในช่วงทดสอบ (100-2000) เธรดเวลาทั้งหมดต่อเธรดดูเหมือนจะคงที่
นี่คือรหัสที่ถูกเปรียบเทียบ:
for (int i = 0; i < ThreadCount; i++) {
Task.Run(() => { });
}
for (int i = 0; i < ThreadCount; i++) {
var t = new Thread(() => { });
t.Start();
}
ตรวจสอบที่นี่สำหรับเธรดก่อนหน้านี้:
เมื่อใดที่ฉันไม่ควรใช้ ThreadPool ใน. Net
สรุปก็คือ Threadpool เป็นสิ่งที่ดีหากคุณต้องการสร้างเธรดแบบสั้นจำนวนมากในขณะที่การใช้เธรดจะช่วยให้คุณควบคุมได้มากขึ้นเล็กน้อย
พื้นที่จัดเก็บเธรดในเครื่องไม่ใช่ความคิดที่ดีสำหรับเธรดพูล มันทำให้เธรดเป็น "เอกลักษณ์"; เธรดทั้งหมดไม่เท่ากันอีกต่อไป ตอนนี้เธรดพูลมีประโยชน์อย่างยิ่งหากคุณต้องการเธรดที่เหมือนกันจำนวนมากพร้อมที่จะทำงานของคุณโดยไม่ต้องสร้างค่าใช้จ่าย
หากคุณต้องการเธรดจำนวนมากคุณอาจต้องการใช้ ThreadPool พวกเขาใช้เธรดซ้ำช่วยให้คุณประหยัดค่าใช้จ่ายในการสร้างเธรด
หากคุณต้องการเพียงเธรดเดียวเพื่อทำบางสิ่งบางอย่างเธรดน่าจะง่ายที่สุด
ความต้องการหลักสำหรับเธรด Adpool คือการจัดการงานสั้น ๆ ที่คาดว่าจะเสร็จสมบูรณ์เกือบจะในทันที ตัวจัดการการขัดจังหวะฮาร์ดแวร์มักจะทำงานในบริบทที่ซ้อนกันซึ่งจะไม่เหมาะสำหรับโค้ดที่ไม่ใช่เคอร์เนล แต่ตัวจัดการการขัดจังหวะฮาร์ดแวร์อาจค้นพบว่าควรเรียกใช้การเรียกกลับการเสร็จสิ้น I / O ในโหมดผู้ใช้โดยเร็วที่สุด การสร้างเธรดใหม่เพื่อจุดประสงค์ในการเรียกใช้สิ่งดังกล่าวจะเป็นการใช้งานมากเกินไป การมีเธรดที่สร้างไว้ล่วงหน้าเพียงไม่กี่เธรดซึ่งสามารถส่งไปเพื่อเรียกใช้การเรียกกลับการเสร็จสิ้น I / O หรือสิ่งอื่นที่คล้ายคลึงกันนั้นมีประสิทธิภาพมากกว่ามาก
ลักษณะสำคัญของเธรดดังกล่าวคือถ้าเมธอดการเติม I / O เสร็จสมบูรณ์โดยทันทีเป็นหลักและไม่บล็อกและจำนวนเธรดดังกล่าวที่รันเมธอดในปัจจุบันอย่างน้อยเท่ากับจำนวนโปรเซสเซอร์วิธีเดียวที่เธรดอื่น ๆ สามารถรันได้ก่อนที่วิธีการใดวิธีการหนึ่งที่กล่าวถึงข้างต้นจะเสร็จสิ้นหากวิธีการอื่นใดบล็อกหรือเวลาดำเนินการเกินกว่าช่วงเวลาเธรดปกติ สิ่งเหล่านี้ไม่ควรเกิดขึ้นบ่อยนักหากมีการใช้เธรดพูลตามที่ตั้งใจไว้
หากไม่สามารถคาดหมายว่าเมธอดจะออกภายใน 100ms เมื่อเริ่มดำเนินการเมธอดควรดำเนินการด้วยวิธีการอื่นที่ไม่ใช่เธรดพูลหลัก หากมีงานจำนวนมากที่ต้องดำเนินการซึ่งมี CPU เข้มข้น แต่จะไม่ปิดกั้นอาจเป็นประโยชน์ในการจัดส่งโดยใช้ชุดเธรดของแอปพลิเคชัน (หนึ่งชุดต่อแกน CPU) ซึ่งแยกจากเธรดพูล "หลัก" เนื่องจากใช้ เธรดที่มากกว่าคอร์จะถูกต่อต้านเมื่อรันงานที่ต้องใช้ CPU มากโดยไม่ปิดกั้น อย่างไรก็ตามหากวิธีการใช้เวลาหนึ่งวินาทีหรือนานกว่านั้นในการดำเนินการและจะใช้เวลาส่วนใหญ่ในการบล็อกเมธอดนั้นควรจะรันในเธรดเฉพาะและแทบจะไม่ถูกรันในเธรดพูลเธรดหลัก หากการดำเนินการที่รันเป็นเวลานานจำเป็นต้องถูกทริกเกอร์โดยบางสิ่งเช่นการเรียกกลับ I / O
โดยทั่วไป (ฉันไม่เคยใช้. NET) เธรดพูลจะถูกใช้เพื่อวัตถุประสงค์ในการจัดการทรัพยากร ช่วยให้สามารถกำหนดค่าข้อ จำกัด ลงในซอฟต์แวร์ของคุณได้ นอกจากนี้ยังอาจทำได้ด้วยเหตุผลด้านประสิทธิภาพเนื่องจากการสร้างเธรดใหม่อาจมีค่าใช้จ่ายสูง
นอกจากนี้ยังอาจมีเหตุผลเฉพาะของระบบ ใน Java (อีกครั้งฉันไม่รู้ว่าสิ่งนี้ใช้กับ. NET หรือไม่) ผู้จัดการของเธรดอาจใช้ตัวแปรเฉพาะของเธรดเนื่องจากแต่ละเธรดถูกดึงออกจากพูลและยกเลิกการตั้งค่าเมื่อส่งคืน (วิธีทั่วไปในการส่งผ่านสิ่งต่างๆเช่น ตัวตน).
ข้อ จำกัด ตัวอย่าง: ฉันมีการเชื่อมต่อ 10 db เท่านั้นดังนั้นฉันจึงอนุญาตเธรดผู้ปฏิบัติงาน 10 เธรดเท่านั้นในการเข้าถึงฐานข้อมูล
นี่ไม่ได้หมายความว่าคุณไม่ควรสร้างเธรดของคุณเอง แต่มีเงื่อนไขที่เหมาะสมที่จะใช้พูล
การใช้พูลเป็นความคิดที่ดีหากคุณไม่รู้หรือไม่สามารถควบคุมได้ว่าจะสร้างเธรดจำนวนเท่าใด
เพียงแค่มีปัญหากับแบบฟอร์มที่ใช้เธรดเพื่ออัปเดตฟิลด์บางส่วนจากฐานข้อมูลในเหตุการณ์ที่มีการเปลี่ยนแปลงตำแหน่งของการควบคุมรายการ (หลีกเลี่ยง freez) ผู้ใช้ของฉันใช้เวลา 5 นาทีในการเกิดข้อผิดพลาดจากฐานข้อมูล (เชื่อมต่อกับ Access มากเกินไป) เพราะเขาเปลี่ยนตำแหน่งรายการเร็วเกินไป ...
ฉันรู้ว่ามีวิธีอื่นในการแก้ไขปัญหาพื้นฐาน (รวมถึงการไม่ใช้การเข้าถึง) แต่การรวมกลุ่มเป็นการเริ่มต้นที่ดี
ด้าย :
เธรด - พูล :