จำนวนกระทู้มีมากเกินไป


312

ฉันกำลังเขียนเซิร์ฟเวอร์และฉันส่งแต่ละการกระทำของลงในเธรดแยกต่างหากเมื่อได้รับการร้องขอ ฉันทำเช่นนี้เพราะเกือบทุกคำขอทำให้แบบสอบถามฐานข้อมูล ฉันใช้ไลบรารีเธรดพูลเพื่อลดการสร้าง / ทำลายเธรด

คำถามของฉันคืออะไรจุดตัดที่ดีสำหรับเธรด I / O เช่นนี้คืออะไร ฉันรู้ว่ามันเป็นเพียงการประมาณการคร่าวๆ แต่เราจะพูดหลายร้อย? พัน?

ฉันจะหาการตัดยอดนี้ได้อย่างไร?


แก้ไข:

ขอบคุณสำหรับคำตอบของคุณดูเหมือนว่าฉันจะต้องทดสอบมันเพื่อหาเพดานการนับด้ายของฉัน คำถามคือ: ฉันจะรู้ได้อย่างไรว่าฉันไปถึงเพดานนั้นแล้ว? ฉันควรวัดอะไรอย่างแน่นอน


1
@ryeguy: จุดทั้งหมดที่นี่คือคุณไม่ควรตั้งค่าสูงสุดในเธรดพูลหากไม่มีปัญหาเกี่ยวกับประสิทธิภาพในการเริ่มต้น คำแนะนำส่วนใหญ่ในการ จำกัด เธรดพูลให้เหลือเพียง 100 เธรดนั้นไร้สาระเธรดพูลส่วนใหญ่จะมี / วิธี / เธรดมากกว่าและไม่เคยมีปัญหา
GEOCHET

ryeguy โปรดดูคำตอบของฉันเพิ่มเติมด้านล่างว่าจะวัดอะไร
paxdiablo

อย่าลืมว่า Python นั้นเป็นธรรมชาติไม่ได้เป็นมิตรกับหลายคน ณ เวลาใดเวลาหนึ่งจะมีการใช้งาน optecode รหัสเดียว นี่เป็นเพราะ Python ใช้ Global Interpreter Lock
ASK

1
@ Jay D: ฉันจะบอกว่าช่วงเวลาที่คุณโดนเพดานคือเมื่อการแสดงของคุณเริ่มลดลง
ninjalj

6
@GEOCHET "จุดทั้งหมดที่นี่คือคุณไม่ควรตั้งค่าสูงสุดในเธรดพูล" Ummm ... พูดอะไรนะ? กลุ่มเธรดที่มีขนาดคงที่มีข้อดีของการลดขนาดและความสามารถในการขยาย เช่นในการตั้งค่าเครือข่ายหากคุณวางไข่เธรดใหม่ตามการเชื่อมต่อไคลเอนต์โดยไม่มีขนาดพูถาวรคุณเรียกใช้อันตรายที่แท้จริงของการเรียนรู้ ( วิธียาก ) จำนวนเธรดเซิร์ฟเวอร์ของคุณสามารถจัดการและไคลเอนต์ที่เชื่อมต่อทุกเดียว จะต้องทนทุกข์ทรมาน สระว่ายน้ำขนาดคงที่ทำหน้าที่เหมือนไพพ์วาล์วโดยการไม่อนุญาตให้เซิร์ฟเวอร์ของคุณพยายามกัดมากกว่าที่จะเคี้ยว
b1nary.atr0phy

คำตอบ:


206

บางคนอาจพูดว่าสองกระทู้มากเกินไป - ฉันไม่ได้อยู่ในค่ายนั้น :-)

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

หากการใช้เธรดของคุณอยู่ที่ 3 หมายถึง 100 จะมากเกินไป หากยังคงอยู่ที่ 100 ตลอดทั้งวันให้ชน 200 และดูว่าเกิดอะไรขึ้น

คุณสามารถมีรหัสของตัวเองตรวจสอบการใช้งานและปรับการตั้งค่าสำหรับครั้งต่อไปที่มันเริ่ม แต่นั่นอาจจะมากเกินไป


สำหรับการชี้แจงและทำอย่างละเอียด:

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

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

  • จำนวนเธรดที่แอ็คทีฟต่ำสุด
  • จำนวนเธรดสูงสุด
  • ปิดกระทู้ที่ไม่ได้ใช้ในขณะที่

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

คุณต้องสมดุลการใช้ทรัพยากรของการมีเธรดที่ไม่ได้ใช้ (A) กับการใช้ทรัพยากรที่มีเธรดไม่เพียงพอที่จะทำงาน (B)

(A) เป็นการใช้งานหน่วยความจำ (สแต็กและอื่น ๆ ) เนื่องจากเธรดที่ทำงานไม่ได้จะไม่ใช้ CPU มากนัก (B) โดยทั่วไปจะมีความล่าช้าในการประมวลผลคำขอในขณะที่พวกเขามาถึงในขณะที่คุณต้องรอให้เธรดพร้อมใช้งาน

นั่นเป็นเหตุผลที่คุณวัด เมื่อคุณระบุเธรดส่วนใหญ่ของคุณจะรอการตอบกลับจากฐานข้อมูลเพื่อไม่ให้เธรดทำงาน มีสองปัจจัยที่มีผลต่อจำนวนเธรดที่คุณควรอนุญาต

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

จากนั้นจำนวนเธรดที่คุณควรขึ้นอยู่กับการใช้งานในอดีตของคุณ จำนวนขั้นต่ำที่คุณควรใช้คือจำนวนขั้นต่ำที่คุณเคยเรียกใช้ + A% ด้วยจำนวนต่ำสุดที่แน่นอน (ตัวอย่างเช่นและทำให้สามารถกำหนดค่าได้เช่นเดียวกับ A) 5

จำนวนเธรดสูงสุดควรเป็นประวัติสูงสุดของคุณ + B%

คุณควรตรวจสอบการเปลี่ยนแปลงพฤติกรรม หากด้วยเหตุผลบางอย่างการใช้งานของคุณไปถึง 100% พร้อมใช้งานในช่วงเวลาที่สำคัญ (เพื่อให้มีผลต่อประสิทธิภาพของลูกค้า) คุณควรชนค่าสูงสุดที่อนุญาตจนกว่าจะสูงขึ้นอีก B% อีกครั้ง


ในการตอบสนองต่อ "ฉันควรวัดอะไร?" คำถาม:

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

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


หากเธรดเกิดจากคำร้องขอที่เข้ามาการใช้เธรดจะทำมิเรอร์จำนวนคำขอที่ไม่ได้รับ ไม่มีวิธีกำหนดหมายเลข "ดีที่สุด" จากสิ่งนี้ แน่นอนคุณจะพบกระทู้เพิ่มเติมทำให้เกิดความขัดแย้งของทรัพยากรมากขึ้นและจำนวนเธรดที่ใช้งานจะเพิ่มขึ้น
Andrew Grant

@ แอนดรูว์การสร้างเธรดต้องใช้เวลาและคุณสามารถกำหนดจำนวนที่เหมาะสมโดยอ้างอิงจากข้อมูลในอดีต [+ N%] (จากการวัดอย่าคาดเดา) นอกจากนี้เธรดเพิ่มเติมจะทำให้เกิดความขัดแย้งของทรัพยากรเมื่อพวกเขาทำงานไม่รอสัญญาณ / สัญญาณ
paxdiablo

ข้อมูลนี้ใน 'การสร้างเธรด' ทำให้เกิดปัญหาประสิทธิภาพเมื่อใช้เธรดพูลหรือไม่ เธรดพูลที่ดีจะไม่สร้างและทำลายเธรดระหว่างงาน
GEOCHET

@Pax หากเธรดทั้งหมดของคุณกำลังรอเซมาฟอเรสเดียวกันเพื่อเรียกใช้คิวรี DB นั่นคือคำจำกัดความของการโต้แย้ง นอกจากนี้ยังไม่เป็นความจริงที่จะพูดว่าเธรดไม่ต้องเสียค่าใช้จ่ายใด ๆ
Andrew Grant

1
@ แอนดรูว์ฉันไม่เห็นสาเหตุที่คุณต้องการส่งสัญญาณบล็อกแบบสอบถาม DB ฐานข้อมูลที่เหมาะสมใด ๆ จะอนุญาตให้เข้าถึงพร้อมกันโดยมีหลายเธรดรอการตอบกลับ และเธรดไม่ควรใช้เวลาดำเนินการใด ๆในขณะที่เซมาฟอร์ถูกบล็อกพวกเขาควรนั่งในคิวที่ถูกบล็อกจนกระทั่งเซมาฟอร์ถูกปล่อยออกมา
paxdiablo

36

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

  1. Thread Stack Size: ใน Linux ขนาดเธรดสแต็กเริ่มต้นคือ 8MB (คุณสามารถใช้ ulimit -a เพื่อค้นหาได้)
  2. หน่วยความจำเสมือนสูงสุดที่ระบบปฏิบัติการรุ่นที่กำหนดสนับสนุน Linux Kernel 2.4 รองรับพื้นที่ที่อยู่หน่วยความจำ 2 GB ด้วย Kernel 2.6 ฉันใหญ่ขึ้นเล็กน้อย (3GB)
  3. [1] แสดงการคำนวณจำนวนเธรดสูงสุดต่อ Max VM ที่รองรับที่ระบุ สำหรับ 2.4 มันจะกลายเป็นประมาณ 255 กระทู้ สำหรับ 2.6 ตัวเลขนั้นใหญ่กว่าเล็กน้อย
  4. คุณมีตัวจัดตารางเวลาเคอร์เนลชนิดใด การเปรียบเทียบตัวจัดตารางเวลาเคอร์เนล Linux 2.4 กับ 2.6 ในภายหลังจะให้การกำหนดเวลา O (1) โดยไม่มีการพึ่งพาจำนวนงานที่มีอยู่ในระบบในขณะที่งานแรกเป็น O (n) มากกว่า ดังนั้นความสามารถของ SMP ของกำหนดการเคอร์เนลจึงมีบทบาทที่ดีในจำนวนเธรดที่ยั่งยืนสูงสุดในระบบ

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

โปรดทราบว่าหนึ่งสามารถสร้างเธรดนับพันตามความต้องการของเขา / เธอ แต่เมื่อลินุกซ์หมดของ VM มันเพียงแค่เริ่มต้นกระบวนการฆ่าแบบสุ่ม (เช่นกระทู้) นี่คือเพื่อป้องกันไม่ให้โปรไฟล์ยูทิลิตี้ถูก maxed out (ฟังก์ชั่นยูทิลิตี้บอกเกี่ยวกับยูทิลิตี้ทั้งระบบสำหรับจำนวนทรัพยากรที่กำหนดด้วยทรัพยากรคงที่ในกรณีนี้วงจร CPU และหน่วยความจำโค้งยูทิลิตี้แบนออกด้วยจำนวนงานมากขึ้น)

ฉันแน่ใจว่าตัวจัดตารางเวลาเคอร์เนลของ windows ยังทำอะไรบางอย่างเพื่อจัดการกับการใช้ทรัพยากร

[1] http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/ 1


17

หากเธรดของคุณกำลังทำงานที่ต้องใช้ทรัพยากรมาก (CPU / Disk) ใด ๆ คุณจะไม่ค่อยเห็นประโยชน์เกินกว่าหนึ่งหรือสองและมากเกินไปจะฆ่าประสิทธิภาพได้อย่างรวดเร็ว

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

ทางออกที่ดีคือการร้องขอในพูลที่ส่งไปยังเธรดผู้ปฏิบัติงานจากเธรดพูล (และใช่การหลีกเลี่ยงการสร้าง / ทำลายเธรดอย่างต่อเนื่องเป็นขั้นตอนแรกที่ยอดเยี่ยม)

จำนวนเธรดที่ใช้งานในกลุ่มนี้สามารถปรับแต่งและปรับขนาดตามการค้นพบโปรไฟล์ของคุณฮาร์ดแวร์ที่คุณใช้งานและสิ่งอื่น ๆ ที่อาจเกิดขึ้นบนเครื่อง


ใช่และควรใช้ร่วมกับคิวหรือกลุ่มของคำขอ
Andrew Grant

2
@Andrew: ทำไม ควรเพิ่มภารกิจในกลุ่มเธรดทุกครั้งที่ได้รับการร้องขอ มันขึ้นอยู่กับเธรดพูลเพื่อจัดสรรเธรดสำหรับงานเมื่อมีหนึ่งเธรดที่พร้อมใช้งาน
GEOCHET

ดังนั้นคุณจะทำอย่างไรเมื่อมีคำขอเข้ามาหลายร้อยรายการและไม่อยู่ในกลุ่ม? สร้างเพิ่มเติมหรือไม่ บล็อก? ส่งคืนข้อผิดพลาดหรือไม่ วางคำร้องขอของคุณในพูลที่มีขนาดใหญ่เท่าที่ต้องการจากนั้นป้อนคำร้องขอที่อยู่ในคิวเหล่านี้ไปยังเธรดพูลของคุณเมื่อเธรดว่าง
Andrew Grant

"จำนวนเธรดถูกสร้างขึ้นเพื่อดำเนินการตามจำนวนงานซึ่งโดยปกติจะมีการจัดระเบียบในคิวโดยทั่วไปจะมีงานมากกว่าเธรดทันทีที่เธรดทำงานเสร็จภารกิจจะของานถัดไปจากคิว จนกว่างานทั้งหมดจะเสร็จสิ้น "
GEOCHET

@Andrew: ฉันไม่แน่ใจว่าไพธูมพูลโปรแกรมใช้งานอะไร แต่ถ้าคุณต้องการตัวอย่างจริงของฟังก์ชั่นนี้ฉันกำลังอธิบาย: msdn.microsoft.com/en-us/library/ …
GEOCHET

10

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

หากคุณต้องการไพ ธ อนแบบมัลติเธรดที่มีประโยชน์สูงสุดจริงๆคุณอาจต้องพิจารณาใช้ Jython หรือบางอย่าง


4
หลังจากอ่านสิ่งนี้ฉันพยายามใช้งาน Eratosthenes ในสามกระทู้ แน่นอนว่ามันช้ากว่าการรันภารกิจเดียวกัน50% ในเธรดเดียว ขอบคุณสำหรับหัวขึ้น. ฉันใช้ Eclipse Pydev บนเครื่องเสมือนที่จัดสรร CPU สองตัว ต่อไปฉันจะลองสถานการณ์ที่เกี่ยวข้องกับการเรียกฐานข้อมูล
Don Kirkby

3
มีสองประเภท (อย่างน้อย) ประเภทของงาน: CPU ที่ถูกผูกไว้ (เช่นการประมวลผลภาพ) และ I / O ที่ถูกผูกไว้ (เช่นการดาวน์โหลดจากเครือข่าย) เห็นได้ชัดว่า GIL "ปัญหา" จะไม่ส่งผลต่อภาระผูกพัน I / O มากเกินไป หากงานของคุณมี CPU ผูกไว้คุณควรพิจารณามัลติโพรเซสเซอร์แทนการมัลติเธรด
iutinvg

1
ใช่ด้ายหลามมีการปรับปรุงถ้าคุณมีจำนวนมากของเครือข่าย io.I เปลี่ยนแปลงที่จะด้ายและได้ 10 * เร็วกว่ารหัสสามัญ ...
TYAN

8

ในฐานะที่ท่านถูกต้องกล่าวว่าวัดไม่ต้องเดา สิ่งที่ฉันทำสำหรับพยาน DNSและผลลัพธ์นั้นน่าประหลาดใจ: จำนวนกระทู้ในอุดมคตินั้นสูงกว่าที่ฉันคิดไว้อย่างมากเช่น 15,000 กระทู้เพื่อให้ได้ผลลัพธ์ที่เร็วที่สุด

แน่นอนมันขึ้นอยู่กับหลาย ๆ สิ่งนั่นเป็นสาเหตุที่คุณต้องวัดตัวเอง

มาตรการที่สมบูรณ์ (เป็นภาษาฝรั่งเศสเท่านั้น) ในCombien de fils d'exécution? .


1
15,000? นั่นสูงกว่าที่ฉันคาดไว้เช่นกัน ถึงกระนั้นถ้านั่นคือสิ่งที่คุณได้รับแล้วนั่นคือสิ่งที่คุณได้รับฉันไม่สามารถโต้เถียงกับที่
paxdiablo

2
สำหรับแอปพลิเคชันเฉพาะนี้เธรดส่วนใหญ่กำลังรอการตอบกลับจากเซิร์ฟเวอร์ DNS ดังนั้นยิ่งมีความเท่าเทียมกันมากเท่าไหร่เวลานาฬิกาแขวนก็ยิ่งมากขึ้นเท่านั้น
bortzmeyer

18
ฉันคิดว่าถ้าคุณมีเธรด 15000 ที่บล็อกไอโอภายนอกบางตัวทางออกที่ดีกว่าจะเป็นเธรดที่น้อยลงอย่างมาก แต่ด้วยโมเดลอะซิงโครนัส ฉันพูดจากประสบการณ์ที่นี่
Steve

5

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

ใส่แตกต่างกันเมื่อคุณถึงคอขวดไม่ว่าจะเป็น CPU, ทรูพุตฐานข้อมูล, ทรูพุตดิสก์ ฯลฯ การเพิ่มเธรดเพิ่มเติมจะไม่เพิ่มประสิทธิภาพโดยรวม แต่จนกว่าคุณจะถึงจุดนั้นให้เพิ่มหัวข้อเพิ่มเติม!

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


1
คุณช่วยพูดถึงจำนวนที่คุณเห็นเพื่อนับจำนวนไหม? มันจะมีประโยชน์ถ้าคุณเข้าใจแล้ว ขอบคุณ
kovac

3

คำตอบ "big iron" โดยทั่วไปคือหนึ่งเธรดต่อทรัพยากรที่ จำกัด - ตัวประมวลผล (CPU ที่ถูกผูกไว้), arm (I / O ที่ถูกผูกไว้) ฯลฯ - แต่ใช้ได้เฉพาะถ้าคุณสามารถกำหนดเส้นทางงานไปยังเธรดที่ถูกต้องสำหรับทรัพยากร เข้าถึงได้

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

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

แน่นอนคุณต้องชั่งน้ำหนักทั้งหมดนี้กับ "น้ำหนัก" ของเธรด น่าเสียดายที่ระบบส่วนใหญ่มีเธรดที่มีน้ำหนักมาก (และสิ่งที่เรียกว่า "เธรดที่มีน้ำหนักเบา" มักไม่ใช่เธรดเลย) ดังนั้นจึงควรดีกว่าที่จะทำผิดพลาดที่ด้านล่าง

สิ่งที่ฉันได้เห็นในทางปฏิบัติคือความแตกต่างที่ลึกซึ้งมากสามารถสร้างความแตกต่างอย่างมากในจำนวนกระทู้ที่เหมาะสม โดยเฉพาะอย่างยิ่งปัญหาแคชและข้อขัดแย้งการล็อคสามารถ จำกัด จำนวนของการทำงานพร้อมกันในทางปฏิบัติ


2

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


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

1
@mmr: อืมไม่ แนวคิดของเธรดคือการอนุญาตให้บล็อก I / O และงานอื่น ๆ
GEOCHET

4
คำสั่งที่ฉันทำคือจำนวนของคอร์ในเครื่องแสดงถึงข้อ จำกัด จำนวนของเธรดที่สามารถทำงานได้ตามเวลาที่กำหนดซึ่งเป็นความจริง แน่นอนว่าเธรดอื่น ๆ สามารถรอการดำเนินการ I / O ให้เสร็จสมบูรณ์และสำหรับคำถามนี้ที่มีการพิจารณาที่สำคัญ
newdayrising

1
อย่างไรก็ตาม - คุณมี GIL ใน Python ซึ่งทำให้เธรดขนานในเชิงทฤษฎีเท่านั้น ไม่สามารถเรียกใช้มากกว่าหนึ่งเธรดได้พร้อมกันดังนั้นจึงเป็นเพียงการตอบสนองและการบล็อกการดำเนินการที่สำคัญ
Abgan

2
+1 สำหรับการทำความเข้าใจวิธีการทำงานของคอมพิวเตอร์ @mmr: คุณต้องเข้าใจถึงความแตกต่างระหว่างดูเหมือนจะมีโปรเซสเซอร์หลายตัวและมีโปรเซสเซอร์หลายตัว @Rich B: กลุ่มเธรดเป็นเพียงหนึ่งในหลายวิธีที่จะจัดการกับชุดของเธรด มันเป็นสิ่งที่ดี แต่ไม่แน่นอนอย่างเดียว
เสียใจ

2

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


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

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

ยุติธรรมพอสมควร ฉันไม่แน่ใจว่าทำไมจึงเป็นเช่นนั้นฉันจึงได้คะแนน -2 ding ยกเว้นว่าผู้คนต้องการเห็นคำตอบของเธรดเท่านั้นแทนที่จะรวมถึงคำตอบอื่น ๆ ที่ใช้งานได้จริง
mmr

@mmr: พิจารณาคำถามเกี่ยวกับ / thread / pool ใช่ฉันคิดว่าผู้คนควรคาดหวังคำตอบเกี่ยวกับกระทู้
GEOCHET

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

1

ryeguy ฉันกำลังพัฒนาแอพพลิเคชั่นที่คล้ายกันและหมายเลขเธรดของฉันถูกตั้งค่าเป็น 15 แต่น่าเสียดายถ้าฉันเพิ่มที่ 20 มันจะล่ม ดังนั้นใช่ฉันคิดว่าวิธีที่ดีที่สุดในการจัดการนี้คือการวัดว่าการกำหนดค่าปัจจุบันของคุณอนุญาตเธรดจำนวนมากขึ้นหรือน้อยลง


5
การเพิ่มไปยังจำนวนเธรดของคุณไม่ควรทำให้แอปพลิเคชันของคุณขัดข้อง มีเหตุผลบางอย่าง คุณควรจะหาสาเหตุเพราะมันอาจส่งผลกระทบคุณแม้จะมีกระทู้น้อยลงในบางสถานการณ์ใครจะรู้
Matthew Lund

-6

ในกรณีส่วนใหญ่คุณควรอนุญาตให้เธรดพูลจัดการสิ่งนี้ หากคุณโพสต์รหัสหรือให้รายละเอียดเพิ่มเติมอาจง่ายกว่าที่จะดูว่ามีเหตุผลบางอย่างที่พฤติกรรมเริ่มต้นของกลุ่มเธรดจะไม่ดีที่สุดหรือไม่

คุณสามารถหาข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานได้ที่นี่: http://en.wikipedia.org/wiki/Thread_pool_pattern


1
@Pax: นี่จะไม่เป็นครั้งแรกที่คนส่วนใหญ่ไม่ต้องการตอบคำถามในมือ (หรือเข้าใจ) ฉันไม่กังวล
GEOCHET

-10

หลาย ๆ เธรดที่เป็นแกน CPU คือสิ่งที่ฉันได้ยินบ่อยมาก


5
@ ริชอย่างน้อยก็อธิบายว่าทำไม :-) กฎของหัวแม่มือนี้ใช้เฉพาะเมื่อเธรดทั้งหมดถูกผูกไว้กับ CPU พวกเขาได้รับ 'CPU' หนึ่งอัน เมื่อเธรดจำนวนมากเป็น I / O ที่ถูกผูกไว้โดยปกติแล้วจะดีกว่าที่จะมีเธรดมากกว่า 'CPU (อ้างถึง CPU เนื่องจากใช้กับเธรดฟิสิคัลของการดำเนินการเช่นคอร์)
paxdiablo

1
@Abgan ฉันไม่แน่ใจเกี่ยวกับเรื่องนั้นคิดว่า Python อาจจะสร้างเธรด OS "ของจริง" (ทำงานบนหลาย CPU) หากสิ่งที่คุณพูดนั้นเป็นความจริง (ฉันไม่มีเหตุผลที่จะสงสัย) ปริมาณของ CPU จะไม่มีการแบก - การทำเกลียวจะมีประโยชน์เฉพาะเมื่อเธรดส่วนใหญ่รออะไรบางอย่าง (เช่น DB I / O)
paxdiablo

1
@ ริช: เมื่อเธรด (ของจริง) นับ CPU มีแบริ่งเนื่องจากคุณสามารถเรียกใช้เธรดที่ไม่รอหลายรายการพร้อมกันได้อย่างแท้จริง ด้วย CPU หนึ่งตัวรันเพียงครั้งเดียวและผลประโยชน์จะเกิดขึ้นจากการมีเธรดอื่น ๆ มากมายรอทรัพยากรที่ไม่ใช่ CPU
paxdiablo

1
@ สันติภาพ: คุณไม่เข้าใจแนวคิดของเธรดพูลดังนั้นฉันเดาว่า
GEOCHET

1
@ ที่อุดมไปด้วยฉันเข้าใจสระว่ายน้ำด้าย; ดูเหมือนว่าฉัน (และคนอื่น ๆ ที่นี่) เข้าใจฮาร์ดแวร์ดีกว่าคุณ ด้วย CPU หนึ่งตัวเธรดการประมวลผลเดียวเท่านั้นที่สามารถเรียกใช้ได้แม้ว่าจะมีเธรดอื่นกำลังรอ CPU อยู่ CPU สองตัวสองตัวสามารถทำงานได้ iff หัวข้อทั้งหมดที่กำลังรอสำหรับซีพียู, นับด้ายเหมาะเท่ากับ ...
paxdiablo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.