จำนวนเธรดสูงสุดต่อกระบวนการใน Linux?


245

จำนวนเธรดสูงสุดที่สามารถสร้างได้โดยกระบวนการภายใต้ Linux คือเท่าใด

จะแก้ไขค่านี้ได้อย่างไร (ถ้าเป็นไปได้)

คำตอบ:


247

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

cat /proc/sys/kernel/threads-max

ค่าเริ่มต้นคือจำนวนหน้าหน่วยความจำ / 4 คุณสามารถเพิ่มเช่นนี้:

echo 100000 > /proc/sys/kernel/threads-max

นอกจากนี้ยังมีข้อ จำกัด เกี่ยวกับจำนวนกระบวนการ (และเธรดด้วยเหตุนี้) ที่ผู้ใช้รายเดียวอาจสร้างขึ้นดูulimit/getrlimitรายละเอียดเกี่ยวกับข้อ จำกัด เหล่านี้


3
ขีด จำกัด ใน / proc / sys / vm / max_map_count อาจ จำกัด จำนวนเธรดเช่นกัน มันควรจะปลอดภัยที่จะเพิ่มขีด จำกัด ที่มากถ้าคุณตีมัน
Mikko Rantalainen

1
Robert: Linux ดำเนินการตามขีด จำกัด กระบวนการโดยทางอ้อม ตรวจสอบคำตอบของฉันสำหรับรายละเอียด;)
codersofthedark

ฉันกำลังพยายามเปลี่ยนสิ่งนี้บน Ubuntu 12.04 ของฉันและมันไม่เปลี่ยนไปตามคำสั่งของคุณ ฉันพยายามเปลี่ยน vi แล้ว แต่ฉันจะได้E667: Fsync failedเมื่อฉันพยายามบันทึกใน vi
Siddharth

4
@dragosrsupercool เธรดสูงสุดจะถูกคำนวณโดยใช้ ram ทั้งหมดไม่มีหน่วยความจำเสมือน
c4f4t0r

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

67

นี่เป็นเรื่องที่ผิดที่จะบอกว่า LINUX ไม่มีเธรดแยกกันต่อการ จำกัด กระบวนการ

Linux ใช้จำนวนเธรดสูงสุดต่อกระบวนการทางอ้อม !!

number of threads = total virtual memory / (stack size*1024*1024)

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

ตรวจสอบเครื่องของคุณ:

หน่วยความจำเสมือนทั้งหมด: ulimit -v(ค่าเริ่มต้นคือไม่ จำกัด ดังนั้นคุณต้องเพิ่มหน่วยความจำ swap เพื่อเพิ่มสิ่งนี้)

ขนาดสแต็ครวม: ulimit -s(ค่าเริ่มต้นคือ 8Mb)

คำสั่งเพื่อเพิ่มค่าเหล่านี้:

ulimit -s newvalue

ulimit -v newvalue

* แทนที่ค่าใหม่ด้วยค่าที่คุณต้องการให้เป็นขีด จำกัด

อ้างอิง:

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/


11
ยกเว้น 3 รายละเอียดเล็ก ๆ น้อย ๆ : 1. ลีนุกซ์ไม่ได้ทำสิ่งนี้, การมีอยู่ของสแต็คและความจริงที่ว่าพื้นที่หน่วยความจำและที่อยู่มีขนาด จำกัด 2. ulimit -sคุณต้องระบุสแต็คของเธรดเมื่อสร้างมันนี้เป็นโดยไม่คำนึงถึง เป็นไปได้มาก (ไม่สมเหตุสมผล แต่เป็นไปได้) ในการสร้างเธรดให้มากที่สุดเท่าที่มี ID เธรดที่เป็นไปได้ ภายใต้ 64 บิต Linux จะเป็นไปได้ "ที่เป็นไปได้" อย่างง่ายดายในการสร้างเธรดมากกว่ามีเธรด ID (แน่นอนว่ามันเป็นไปไม่ได้ 3. กองหนุนสำรองคอมมิชชันและ VM เป็นสิ่งที่แตกต่างโดยใช้ OC
Damon

ใช่เพื่อเพิ่มจำนวนกระทู้คุณต้องเพิ่มหน่วยความจำเสมือนหรือลดขนาดสแต็ค ใน Raspberry Pi ฉันไม่พบวิธีเพิ่มหน่วยความจำเสมือนถ้าลดขนาดสแต็กจากค่าเริ่มต้น 8MB เป็น 1MB เป็นไปได้ที่อาจได้รับมากกว่า 1,000 เธรดต่อกระบวนการ แต่ลดขนาดสแต็กด้วยคำสั่ง“ ulimit -s” ทำสิ่งนี้สำหรับหัวข้อทั้งหมด ดังนั้นทางออกของฉันคือใช้ "pthread_t" อินสแตนซ์ "คลาสเธรด" เนื่องจาก pthread_t ให้ฉันตั้งขนาดสแต็คต่อแต่ละเธรด ในที่สุดฉันก็สามารถเก็บมากกว่า 1,000 กระทู้ต่อกระบวนการใน Raspberry Pi แต่ละคนมี 1MB ของกอง
Deulis

43

ในแง่การปฏิบัติข้อ จำกัด มักจะถูกกำหนดโดยพื้นที่สแต็ค หากแต่ละเธรดได้รับสแต็ค 1MB (ฉันจำไม่ได้ว่าเป็นค่าเริ่มต้นบน Linux) จากนั้นระบบ 32- บิตของคุณจะหมดพื้นที่ที่อยู่หลังจาก 3000 เธรด (สมมติว่า gb สุดท้ายถูกสงวนไว้กับเคอร์เนล) .

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

คุณกำลังทำอะไรที่ข้อ จำกัด นี้เกี่ยวข้องกับ?


3
1MB ต่อเธรดสำหรับสแต็กค่อนข้างสูงหลายโปรแกรมไม่ต้องการที่ใดก็ได้ใกล้กับพื้นที่สแต็กจำนวนมาก ประสิทธิภาพจะขึ้นอยู่กับจำนวนของกระบวนการที่รันได้ไม่ใช่จำนวนเธรดที่มีอยู่ ฉันมีเครื่องจักรที่ทำงานในขณะนี้ด้วย 1200+ เธรดที่โหลด 0.40
Robert Gamble

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

สแต็คมีการเติบโตแบบไดนามิกเฉพาะหน้าเริ่มต้นเท่านั้นที่ถูกจัดสรรนอกค้างคาว
Michael Pankov

28

หัวข้อ 100k ที่เหมาะสมบน linux:

ulimit -s  256
ulimit -i  120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max 

 ./100k-pthread-create-app

อัปเดต 2018 จาก @Thomas บนระบบ systemd:

/etc/systemd/logind.conf: UserTasksMax=100000

4
ขอบคุณในที่สุดก็อนุญาตให้ฉันผ่านจำนวนเธรด Java 32k
berezovskyi

1
ใช้งานไม่ได้สำหรับฉัน: $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / kernel / threads-max 127626 $ cat / proc / sys / vm / max_map_count 600000 $ cat / proc / sys / kernel / pid_max 200000 $ java -Xmx4G -Xss256k -cp ThreadCreation ... 11542 11543 java.lang.OutOfMemoryError: ไม่สามารถสร้างเธรดเนทีฟใหม่ที่ java.lang.Thread.start0 (วิธีเนทีฟ) ที่ java.lang.Thread.start (Thread.java:717) ที่ ThreadCreation.main ( ThreadCreation.java:15)
Martin Vysny

@MartinVysny ulimit -s = ขนาดเธรดเป็น kb ดังนั้นคุณพยายามสร้างเธรดที่มีขนาดสแต็กขนาด 100MB
Vladimir Kunschikov

เพิ่มข้อเสนอแนะของคุณโดยไม่ตรวจสอบ @Thomas ขอบคุณสำหรับความคิดเห็น
Vladimir Kunschikov

2
@VladimirKunschikov ขอบคุณเพื่อนวิธีแก้ปัญหาของคุณใช้งานได้จริงและขอบคุณ Thomas เพื่อเพิ่มบรรทัดเพิ่มเติมนั้นฉันสามารถยืนยันได้ว่ามันจะไม่ทำงานโดยไม่ต้องใช้บรรทัดนั้น
BillHoo

14

@dragosrsupercool

Linux ไม่ได้ใช้หน่วยความจำเสมือนในการคำนวณจำนวนเธรดสูงสุด แต่มีการติดตั้งหน่วยความจำจริงบนระบบ

 max_threads = totalram_pages / (8 * 8192 / 4096);

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/

เคอร์เนล / fork.c

/* The default maximum number of threads is set to a safe
 * value: the thread structures can take up at most half
 * of memory.
 */
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

ดังนั้น thread max จะแตกต่างกันไปในทุกระบบเพราะ RAM ที่ติดตั้งมาจากหลายขนาดฉันรู้ว่า Linux ไม่จำเป็นต้องเพิ่มหน่วยความจำเสมือนเพราะใน 32 บิตเรามี 3 GB สำหรับพื้นที่ผู้ใช้และ 1 GB สำหรับเคอร์เนล บน 64 บิตเราได้หน่วยความจำเสมือน 128 TB ที่เกิดขึ้นบน Solaris ถ้าคุณต้องการเพิ่มหน่วยความจำเสมือนที่คุณต้องเพิ่มพื้นที่สว็อป


11

วิธีดึงข้อมูล:

cat /proc/sys/kernel/threads-max

วิธีตั้งค่า:

echo 123456789 > /proc/sys/kernel/threads-max

123456789 = # ของเธรด


ฉันได้รับอนุญาตปฏิเสธเมื่อพยายามที่จะเขียนแม้จะมีรูต
คิม

เกือบสิบปีแล้วที่โพสต์ข้อความนี้ ฉันไม่ทันสมัยเกี่ยวกับสถานะของกิจการในปัจจุบัน แต่อาจมีการเปลี่ยนแปลงมากมาย (และอาจมี) ...
Vincent Van Den Berghe

ปัญหาเกี่ยวกับการอนุญาตปฏิเสธอาจจะผนวก ( >) ส่วนที่สูญเสียsudo: ลองecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson

10

การ จำกัด จำนวนเธรด:

$ cat /proc/sys/kernel/threads-max 

มันคำนวณอย่างไร:

max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

และ: ขนาดหน้า x86_64 (PAGE_SIZE) คือ 4K; เช่นเดียวกับสถาปัตยกรรมอื่น ๆ ทั้งหมด x86_64 มีเคอร์เนลสแต็กสำหรับทุกเธรดที่ใช้งานอยู่ กลุ่มสแต็กเหล่านี้มีขนาดใหญ่ THREAD_SIZE (2 * PAGE_SIZE)

สำหรับ mempages:

cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';

ดังนั้นจำนวนที่ไม่เกี่ยวข้องกับข้อ จำกัด ของขนาดหน่วยความจำของสแต็กเธรด ( ulimit -s)

PS: ข้อ จำกัด ของหน่วยความจำของเธรดสแต็กคือ 10M ใน rhel VM ของฉันและสำหรับหน่วยความจำ 1.5G, VM นี้สามารถจ่ายได้ 150 เธรดเท่านั้น?


5

สำหรับทุกคนที่ดูสิ่งนี้ในระบบ systemd (ในกรณีของฉันโดยเฉพาะ Ubuntu 16.04) มีข้อ จำกัด อื่นบังคับใช้โดยพารามิเตอร์ cgroup pids.max

นี้ถูกตั้งค่าเป็น 12,288 โดยค่าเริ่มต้นและสามารถ overriden ใน /etc/systemd/logind.conf

คำแนะนำอื่น ๆ ยังคงใช้รวมถึง pids_max, threads-max, max_maps_count, ulimits, ฯลฯ


5

ตรวจสอบขนาด stack ต่อ thread ด้วย ulimit ในกรณีของฉัน Redhat Linux 2.6:

    ulimit -a
...
    stack size              (kbytes, -s) 10240

แต่ละเธรดของคุณจะได้รับหน่วยความจำจำนวนนี้ (10MB) สำหรับสแต็กของมัน ด้วยโปรแกรม 32 บิตและพื้นที่ที่อยู่สูงสุด 4GB นั่นคือสูงสุดเพียง 4096MB / 10MB = 409 กระทู้ !!! ลบรหัสโปรแกรมลบฮีปพื้นที่อาจนำไปสู่การสูงสุดที่สังเกตได้ จาก 300 หัวข้อ

คุณควรจะสามารถยกระดับสิ่งนี้ได้โดยการคอมไพล์และรันบน 64 บิตหรือตั้งค่า ulimit -s 8192 หรือแม้กระทั่ง ulimit -s 4096 แต่ถ้าแนะนำให้ทำเช่นนี้จะเป็นการสนทนาอื่น ...


4

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


3
วัตถุประสงค์ของการมัลติเธรดไม่ได้เป็นเพียงประสิทธิภาพ ตัวอย่างเช่นคุณกำลังฟัง 10 พอร์ตด้วยระบบบล็อกในโปรเซสเซอร์ 4 คอร์ ในตัวอย่างนี้ไม่มีความหมายของ 4
obayhan

3

ใช้nbio ไลบรารี i / o ที่ไม่มีการบล็อกหรืออะไรก็ตามถ้าคุณต้องการเธรดเพิ่มเติมสำหรับการโทร I / O ที่บล็อกนั้น


2

ขึ้นอยู่กับระบบของคุณเพียงแค่เขียนโปรแกรมตัวอย่าง [โดยการสร้างกระบวนการในวง] และตรวจสอบการใช้ ps axo pid, ppid, rss, vsz, nlwp, cmd เมื่อไม่สามารถสร้างเธรดได้อีกต่อไปให้ตรวจสอบการนับ nlwp [nlwp คือเธรดตัวเลข] voila คุณจะได้คำตอบที่โง่เขลาแทนที่จะไปถึงหนังสือ



0

เราสามารถดูจำนวนสูงสุดของเธรดที่กำหนดไว้ในไฟล์ต่อไปนี้ใน linux

cat / proc / sys / kernel / threads-max

(หรือ)

sysctl -a | grep threads-max


0

คุณสามารถดูค่าปัจจุบันได้โดย command- cat / proc / sys / kernel / threads-max ต่อไปนี้

คุณสามารถตั้งค่าเช่น

echo 100500> / proc / sys / kernel / threads-max

ค่าที่คุณตั้งไว้จะถูกตรวจสอบกับหน้า RAM ที่มีอยู่ หากโครงสร้างเธรดมีมากกว่า 1 ใน 8 ของเพจ RAM ที่มีอยู่ thread-max จะลดลงตามลำดับ


0

ใช่เพื่อเพิ่มจำนวนกระทู้คุณต้องเพิ่มหน่วยความจำเสมือนหรือลดขนาดสแต็ค ใน Raspberry Pi ฉันไม่พบวิธีเพิ่มหน่วยความจำเสมือนถ้าลดขนาดสแต็กจากค่าเริ่มต้น 8MB เป็น 1MB เป็นไปได้ที่อาจได้รับมากกว่า 1,000 เธรดต่อกระบวนการ แต่ลดขนาดสแต็กด้วยคำสั่ง "ulimit -s" ทำสิ่งนี้สำหรับหัวข้อทั้งหมด ดังนั้นทางออกของฉันคือใช้ "pthread_t" อินสแตนซ์ "คลาสเธรด" เนื่องจาก pthread_t ให้ฉันตั้งขนาดสแต็คต่อแต่ละเธรด ในที่สุดฉันก็สามารถเก็บมากกว่า 1,000 เธรดต่อกระบวนการใน Raspberry Pi แต่ละรายการด้วยสแต็ก 1MB

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.