लिनक्स में प्रति प्रक्रिया थ्रेड की अधिकतम संख्या?


245

लिनक्स के तहत एक प्रक्रिया द्वारा बनाए जा सकने वाले थ्रेड्स की अधिकतम संख्या क्या है?

इस मूल्य को कैसे (यदि संभव हो) संशोधित किया जा सकता है?

जवाबों:


247

लिनक्स में प्रक्रिया की सीमा के अनुसार एक अलग थ्रेड नहीं है, सिस्टम पर प्रक्रियाओं की कुल संख्या पर एक सीमा (थ्रेड अनिवार्य रूप से लिनक्स पर एक साझा पता स्थान के साथ प्रक्रियाएं हैं) जिसे आप इस तरह देख सकते हैं:

cat /proc/sys/kernel/threads-max

डिफ़ॉल्ट मेमोरी पेज / 4 की संख्या है। आप इसे इस तरह बढ़ा सकते हैं:

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

प्रक्रियाओं की संख्या (और इसलिए धागे) पर एक सीमा भी है जो एक एकल उपयोगकर्ता बना सकता है, ulimit/getrlimitइन सीमाओं के बारे में विवरण देखें ।


3
/ Proc / sys / vm / max_map_count में सीमा भी थ्रेड की संख्या को सीमित कर सकती है। यदि आप इसे मारते हैं तो उस सीमा को बहुत अधिक बढ़ाना सुरक्षित होना चाहिए।
मिकको रैंटलैनेन

1
रॉबर्ट: लिनक्स अप्रत्यक्ष रूप से प्रति प्रक्रिया सीमा को लागू करता है। विवरण के लिए मेरे उत्तर की जांच करें;)
कोडरफॉथडार्क

मैं अपने ubuntu 12.04 पर इसे बदलने की कोशिश कर रहा हूं और यह आपकी आज्ञा से नहीं बदल रहा है। मैंने इसे बदलने के लिए vi की भी कोशिश की, लेकिन मुझे E667: Fsync failedतब मिलता है जब मैं vi पर बचत करने की कोशिश करता हूं।
सिद्धार्थ

4
@dragosrsupercool अधिकतम थ्रेड की गणना कुल RAM का उपयोग करके की जाती है, कोई वर्चुअल मेमोरी नहीं
c4f4t0r

1
प्रति थ्रेड आकार की मात्रा (आपके सिस्टम पर डिफ़ॉल्ट) कुछ और की तुलना में सीमा होने की अधिक संभावना है। प्रति-थ्रेड स्टैक आकार को कम करना थ्रेड्स की कुल संख्या को बढ़ाने का एक तरीका है (हालांकि यह शायद ही कभी एक अच्छा विचार है)।
रैंडी हॉवर्ड

67

यह कहना गलत है कि LINUX की प्रक्रिया सीमा प्रति एक अलग सूत्र नहीं है।

लिनक्स प्रति प्रक्रिया अप्रत्यक्ष रूप से अधिकतम संख्या में धागे लागू करता है !!

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

इस प्रकार, कुल वर्चुअल मेमोरी को बढ़ाकर या स्टैक के आकार को घटाकर प्रति प्रोसेस थ्रेड्स की संख्या बढ़ाई जा सकती है। लेकिन, स्टैक का आकार कम होने से स्टैक ओवरफ्लो के कारण कोड विफलता हो सकती है जबकि अधिकतम वर्चुअल मेमोरी स्वैप मेमोरी के बराबर होती है।

आप मशीन की जाँच करें:

कुल वर्चुअल मेमोरी: ulimit -v(डिफ़ॉल्ट असीमित है, इस प्रकार आपको इसे बढ़ाने के लिए स्वैप मेमोरी बढ़ाने की आवश्यकता है)

कुल स्टैक आकार: 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। यह बहुत अच्छी तरह से संभव है (समझदार नहीं है, लेकिन संभव है) के रूप में कई धागे बनाने के लिए संभव धागा आईडी हैं। 64 बिट लिनक्स के तहत, थ्रेड आईडी की तुलना में अधिक थ्रेड्स बनाने के लिए यह आसानी से "संभव" है (बेशक यह संभव नहीं है, लेकिन जहां तक ​​स्टैक जाता है, यह है)। 3. स्टैक रिजर्व, कमिट और वीएम अलग-अलग चीजें हैं, जो ओसी के साथ हैं।
डेमन

हां, थ्रेड्स संख्या बढ़ाने के लिए आपको वर्चुअल मेमोरी बढ़ाने या स्टैक आकार को कम करने की आवश्यकता है। रास्पबेरी पाई में मुझे वर्चुअल मेमोरी को बढ़ाने का एक तरीका नहीं मिला, अगर डिफ़ॉल्ट 8MB से 1MB तक स्टैक का आकार घटता है, तो संभवतः इसे प्रति प्रक्रिया 1000 से अधिक धागे मिलते हैं, लेकिन "ulimit -s" कमांड के साथ स्टैक का आकार घटाते हैं इसे सभी थ्रेड्स के लिए बनाएं। इसलिए, मेरे समाधान का उपयोग "pthread_t" उदाहरण "थ्रेड क्लास" के रूप में किया गया था क्योंकि pthread_t मुझे प्रत्येक थ्रेड के प्रति स्टैक आकार सेट करने देता है। अंत में, मैं रास्पबेरी पाई में प्रत्येक प्रक्रिया में 1000 से अधिक धागे प्रति संग्रह करने के लिए उपलब्ध हूं, प्रत्येक 1 एमबी स्टैक के साथ
देउलिस

43

व्यावहारिक रूप से, सीमा आमतौर पर स्टैक स्पेस द्वारा निर्धारित की जाती है। यदि प्रत्येक थ्रेड में 1 एमबी स्टैक मिलता है (मुझे याद नहीं है कि लिनक्स पर डिफ़ॉल्ट है), तो आप एक 32-बिट सिस्टम 3000 थ्रेड्स के बाद पता स्थान से बाहर चला जाएगा (यह मानते हुए कि अंतिम जीबी कर्नेल के लिए आरक्षित है) ।

हालाँकि, यदि आप कुछ दर्जन से अधिक थ्रेड्स का उपयोग करते हैं, तो आपको सबसे अधिक भयानक प्रदर्शन का अनुभव होगा। जल्दी या बाद में, आप बहुत अधिक संदर्भ-स्विचिंग ओवरहेड प्राप्त करते हैं, शेड्यूलर में बहुत अधिक ओवरहेड, और इसी तरह। (बड़ी संख्या में थ्रेड्स बनाने से मेमोरी बहुत कम हो जाती है, लेकिन वास्तविक काम करने के लिए बहुत सारे थ्रेड आपको धीमा करने जा रहे हैं क्योंकि वे उपलब्ध सीपीयू समय के लिए लड़ रहे हैं)

आप क्या कर रहे हैं जहां यह सीमा और भी प्रासंगिक है?


3
स्टैक के लिए 1 एमबी प्रति थ्रेड बहुत अधिक है, कई कार्यक्रमों को इस स्टैक स्पेस के पास कहीं भी ज़रूरत नहीं है। प्रदर्शन चलने योग्य प्रक्रियाओं की संख्या के आधार पर होने जा रहा है, न कि थ्रेड्स की संख्या जो मौजूद हैं। मेरे पास अभी एक मशीन है जो 0.40 के लोड के साथ 1200+ थ्रेड्स के साथ चल रही है।
रॉबर्ट गैंबल

13
प्रदर्शन थ्रेड्स क्या कर रहे हैं पर निर्भर करता है। यदि वे ऐसा नहीं करते हैं और इसलिए कम संदर्भ-स्विचिंग करते हैं, तो आप कुछ दर्जन से अधिक हो सकते हैं।
कोरी गोल्डबर्ग

स्टैक गतिशील रूप से बढ़ रहा है, केवल प्रारंभिक पृष्ठ को ऑफ-द-बैट आवंटित किया जाता है
माइकल पैंकोव

28

लिनक्स पर उचित 100k धागे:

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

सिस्टम सिस्टम पर @Thomas से 2018 अपडेट:

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

4
धन्यवाद, इसने अंततः मुझे 32k जावा थ्रेड काउंट के माध्यम से तोड़ने की अनुमति दी।
berezovskyi

1
मेरे लिए काम नहीं करता है: $ ulimit -s 100000 $ ulimit -i 63645 $ बिल्ली / proc / sys / कर्नेल / थ्रेड्स-अधिकतम 127626 $ cat / proc / sys / vm / max_map_ount 600000 $ cat / proc / sys / कर्नेल pid_max 200000 $ java -Xmx4G -Xss256k -cp ThreadCreation ... 11542 11543 java.lang.OutOfMemoryError: java.lang.Thread.start0 (मूल विधि) पर java.lang.Tread.start.start (Thread.java:717) पर नए देशी धागे बनाने में असमर्थ। ThreadCreation.java:15)
मार्टिन

@MartinVysny ulimit -s = केबी में धागा का आकार। तो आप 100MB थ्रेड स्टैक आकार के साथ थ्रेड बनाने का प्रयास कर रहे हैं।
व्लादिमीर कुंशिकोव

जाँच के बिना अपना सुझाव जोड़ा, @ थोमस, वैसे भी प्रतिक्रिया के लिए धन्यवाद।
व्लादिमीर कुंशिकोव

2
@VladimirKunschikov धन्यवाद दोस्त, आपके समाधान ने वास्तव में काम किया, और धन्यवाद थॉमस को उस अतिरिक्त लाइन को जोड़ने के लिए, मैं पुष्टि कर सकता हूं कि यह उस लाइन के साथ काम नहीं करेगा।
BillHoo

14

@dragosrsupercool

लिनक्स थ्रेड की अधिकतम गणना करने के लिए वर्चुअल मेमोरी का उपयोग नहीं करता है, लेकिन सिस्टम पर स्थापित भौतिक रैम

 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);

इसलिए थ्रेड मैक्स हर सिस्टम के बीच अलग होता है, क्योंकि इंस्टॉल किया गया रैम अलग-अलग साइज का हो सकता है, मुझे पता है कि लिनक्स को वर्चुअल मेमोरी बढ़ाने की जरूरत नहीं है, क्योंकि 32 बिट पर हमें यूजर स्पेस के लिए 3 जीबी और कर्नेल के लिए 1 जीबी मिलता है। 64 बिट पर हमें 128 टीबी की वर्चुअल मेमोरी मिली है, जो सोलारिस पर होती है, अगर आप वर्चुअल मेमोरी को बढ़ाना चाहते हैं तो आपको स्वैप स्पेस जोड़ना होगा।


11

इसे पुनः प्राप्त करने के लिए:

cat /proc/sys/kernel/threads-max

इसे सेट करने के लिए:

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

123456789 = # धागों का


मुझे लिखने की अनुमति देने से इनकार कर दिया जाता है, यहां तक ​​कि जड़ से भी।
किम

खैर, यह पोस्ट किए गए लगभग एक दशक हो गए हैं। मैं मामलों की वर्तमान स्थिति पर तारीख तक नहीं हूँ, लेकिन बहुत कुछ बदल गया है (और शायद हो सकता है) ...
विन्सेन्ट वान डेन बर्घे

परमिट-अस्वीकार के साथ मुद्दा हो सकता है ( >) हिस्सा खो देता है 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) बड़े हैं;

यादों के लिए:

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

इसलिए वास्तव में संख्या थ्रेड मेमोरी स्टैक आकार ( ulimit -s) की सीमा से संबंधित नहीं है ।

पुनश्च: थ्रेड मेमोरी स्टैक लिमिटेशन मेरे आरएम वीएम में 10 एम है, और 1.5 जी मेमोरी के लिए, यह वीएम केवल 150 धागे खरीद सकता है?


5

अब इसे देखने वाले किसी के लिए, systemd सिस्टम पर (मेरे मामले में, विशेष रूप से Ubuntu 16.04) cgroup pids.max पैरामीटर द्वारा लागू एक और सीमा है।

यह डिफ़ॉल्ट रूप से 12,288 पर सेट है, और /etc/systemd/logind.conf में ओवरराइड किया जा सकता है

अन्य सलाह अभी भी लागू होती हैं जिनमें pids_max, थ्रेड्स-मैक्स, max_maps_count, ulimits, आदि शामिल हैं।


5

ulimit के साथ प्रति थ्रेड आकार की जांच करें, मेरे मामले में Redhat Linux 2.6:

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

आपके प्रत्येक थ्रेड को मेमोरी की यह राशि (10MB) मिल जाएगी जिसे स्टैक के लिए सौंपा गया है। एक 32 बिट प्रोग्राम और 4GB की अधिकतम एड्रेस स्पेस के साथ, जो कि केवल 4096MB / 10MB = 409 थ्रेड्स की अधिकतम सीमा है !!! माइनस प्रोग्राम कोड, माइनस हीप-स्पेस संभवत: एक अधिकतम मनाया जाएगा। 300 धागे का।

आपको इसे 64bit पर संकलित और चलाने या ulimit -s 8192 या यहां तक ​​कि ulimit -s 4096 पर सेट करने में सक्षम होना चाहिए। लेकिन अगर यह उचित है, तो यह एक और चर्चा है ...


4

शायद यह बात नहीं होनी चाहिए। आप एक निश्चित संख्या में थ्रेड (जैसे, 4 या 8 यदि आपके पास 4 प्रोसेसर हैं) का उपयोग करने के लिए अपने एल्गोरिथ्म को डिजाइन करने के लिए बहुत बेहतर प्रदर्शन प्राप्त करने जा रहे हैं। आप इसे काम की कतारों, अतुल्यकालिक IO, या libevent जैसी किसी चीज़ से कर सकते हैं।


3
मल्टीथ्रेडिंग का उद्देश्य केवल प्रदर्शन नहीं है। उदाहरण के लिए आप 4 कोर प्रोसेसर पर ब्लॉकिंग सिस्टम के साथ 10 पोर्ट सुन रहे हैं। इस उदाहरण में 4. का कोई अर्थ नहीं है
obayhan

3

nbio यदि आप उस ब्लॉक को I / O कॉल करने के लिए अधिक थ्रेड्स की आवश्यकता है, तो नॉन-ब्लॉकिंग i / o लाइब्रेरी या जो भी हो, का उपयोग करें


2

आपके सिस्टम पर निर्भर करता है, बस एक नमूना कार्यक्रम लिखें [लूप में प्रक्रियाएं बनाकर] और ps axo pid, ppid, rss, vsz, nlwp, cmd का उपयोग करके जांचें। जब यह थ्रेड्स नहीं बना सकता है तो चेक करें nlwp काउंट [nlwp नम्बर थ्रेड्स है] वॉइला आपको थ्रू किताबों के बजाय अपने मूर्खतापूर्ण उत्तर मिला



0

हम लिनक्स में निम्नलिखित फ़ाइल में परिभाषित थ्रेड्स की अधिकतम संख्या देख सकते हैं

cat / proc / sys / कर्नेल / थ्रेड-मैक्स

(या)

sysctl -a | grep थ्रेड-मैक्स


0

आप निम्न कमांड द्वारा वर्तमान मूल्य देख सकते हैं- कैट / प्रोक / सीस / कर्नेल / थ्रेड्स-मैक्स

आप जैसे मान सेट कर सकते हैं

इको 100500> / proc / sys / कर्नेल / थ्रेड्स-मैक्स

आपके द्वारा सेट किया गया मान उपलब्ध RAM पृष्ठों के विरुद्ध जांचा जाएगा। यदि थ्रेड संरचनाएँ उपलब्ध RAM पेजों में से 1/8 वें स्थान पर रहती हैं, तो तदनुसार थ्रेड-मैक्स कम हो जाएगा।


0

हां, थ्रेड्स संख्या बढ़ाने के लिए आपको वर्चुअल मेमोरी बढ़ाने या स्टैक आकार को कम करने की आवश्यकता है। रास्पबेरी पाई में मुझे वर्चुअल मेमोरी को बढ़ाने का एक तरीका नहीं मिला, अगर डिफ़ॉल्ट 8MB से 1MB तक स्टैक का आकार घटता है, तो संभवतः इसे प्रति प्रक्रिया 1000 से अधिक धागे मिलते हैं, लेकिन "ulimit -s" कमांड के साथ स्टैक का आकार घटाते हैं इसे सभी थ्रेड्स के लिए बनाएं। तो, मेरा समाधान "pthread_t" उदाहरण "थ्रेड क्लास" का उपयोग किया गया था क्योंकि pthread_t मुझे प्रत्येक थ्रेड प्रति स्टैक आकार सेट करने देता है। अंत में, मैं 1 एमबी स्टैक के साथ प्रत्येक रास्पबेरी पाई में प्रति प्रोसेस 1000 से अधिक धागे संग्रह करने के लिए उपलब्ध हूं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.