2010-08-19 7 views
5

निम्नलिखित कोड 100000 धागे बनाने के लिए माना जाता है:एनपीटीएल 65528 पर अधिकतम धागे कैप्स करता है?

/* compile with: gcc -lpthread -o thread-limit thread-limit.c */ 
/* originally from: http://www.volano.com/linuxnotes.html */ 

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <string.h> 

#define MAX_THREADS 100000 
int i; 

void run(void) { 
    sleep(60 * 60); 
} 

int main(int argc, char *argv[]) { 
    int rc = 0; 
    pthread_t thread[MAX_THREADS]; 
    printf("Creating threads ...\n"); 
    for (i = 0; i < MAX_THREADS && rc == 0; i++) { 
    rc = pthread_create(&(thread[i]), NULL, (void *) &run, NULL); 
    if (rc == 0) { 
     pthread_detach(thread[i]); 
     if ((i + 1) % 100 == 0) 
    printf("%i threads so far ...\n", i + 1); 
    } 
    else 
    { 
     printf("Failed with return code %i creating thread %i (%s).\n", 
     rc, i + 1, strerror(rc)); 

     // can we allocate memory? 
     char *block = NULL; 
     block = malloc(65545); 
     if(block == NULL) 
     printf("Malloc failed too :(\n"); 
     else 
     printf("Malloc worked, hmmm\n"); 
    } 
    } 
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use 
    exit(0); 
} 

यह रैम 32GB के साथ एक 64 बिट मशीन पर चल रहा है; डेबियन 5.0 स्थापित, सभी स्टॉक।

  • ulimit -s 512 ढेर आकार रखने के लिए नीचे
  • /proc/sys/कर्नेल/pid_max 1,000,000 करने के लिए सेट (डिफ़ॉल्ट रूप से, यह पता 32k पीआईडी ​​पर कैप्स)।
  • ulimit -u 1000000 अधिकतम प्रक्रियाओं
  • /proc/sys/कर्नेल/धागे-अधिकतम सेट 1000000 (यह सब मायने रखती है नहीं लगता है) (डिफ़ॉल्ट रूप से, यह बिल्कुल सेट नहीं था)
  • को बढ़ाने के लिए

इस बाहर थूक निम्नलिखित चल रहा है:

65500 threads so far ... 
Failed with return code 12 creating thread 65529 (Cannot allocate memory). 
Malloc worked, hmmm 

मैं निश्चित रूप से राम से बाहर नहीं चल रहा हूँ; मैं इन कार्यक्रमों में से कई को एक ही समय में चलाना शुरू कर सकता हूं और वे सभी अपने 65k धागे शुरू करते हैं।

(कृपया मुझे 100,000+ धागे शुरू करने की कोशिश नहीं सुझाव से बचना। यह कुछ ऐसा है जो चाहिए काम करते हैं। मेरे वर्तमान epoll आधारित सर्वर लगभग 200k + और हर समय कनेक्शन various papers है की साधारण परीक्षण है कि धागे सिर्फ सुझाव है कि है एक बेहतर विकल्प हो सकता है। - धन्यवाद :))

+0

'ulimit -s 512' वास्तव में कम से कम ढेर आकार 512 किलोबाइट, नहीं 512 बाइट्स करने के लिए सेट करता है। तो 100,000 धागे के साथ जो लगभग 50 जीबी होगा (हालांकि, यह समस्या नहीं है, क्योंकि ढेर मांग-आवंटित हैं)। – caf

+0

हां, मैंने इसे केवल ulimit -s 1 पर सेट करने का प्रयास किया है और 65528 धागे का परिणाम समान है। वही अगर मैं उस मामले के लिए ulimit-1024 का उपयोग करता हूं। – rekamso

+1

क्या आप स्ट्रिंग (और धैर्य) के साथ पुष्टि कर सकते हैं कि अंतिम pthread_create (क्लोन (2)?) कॉल वास्तव में ENOMEM के साथ विफल रहता है? क्या मूल्य हैं, और यदि आप '/ proc/sys /' फ़ाइलों को बढ़ाते हैं तो क्या होता है: 'vm/max_map_count',' kernel/pid_max' और 'कर्नेल/थ्रेड-अधिकतम'? – pilcrow

उत्तर

6

पायलक्रो का उल्लेख /proc/sys/vm/max_map_count का सही ट्रैक पर है; इस मूल्य को बढ़ाने से अधिक धागे खोले जा सकते हैं; सटीक फॉर्मूला शामिल नहीं है, लेकिन एक 1 मिली + मान कुछ 300k + धागे के लिए अनुमति देता है।

(किसी और 100k + धागे के साथ प्रयोग करने के लिए, pthread_create's mmap मुद्दों पर लग रहे हो ... नया सूत्र बनाने हो जाता है वास्तव में धीमी गति से वास्तव में तेजी से जब कम स्मृति को प्रयोग किया जाता है।)

0

एक संभावित मुद्दा स्थानीय प्रोग्राम thread मुख्य कार्यक्रम में है। मुझे लगता है कि pthread_t आपकी 64-बिट मशीन पर 8 बाइट होगा (64-बिट बिल्ड मानते हुए)। यह ढेर पर 800,000 बाइट होगा। 512 के की आपकी स्टैक सीमा मुझे लगता है कि एक समस्या होगी। 512 के/8 = 65536, जो आपके द्वारा बनाए जा रहे धागे की संख्या के पास संदिग्ध रूप से है। आप उस सरणी को गतिशील रूप से स्टैक पर रखने की बजाय आवंटित करने का प्रयास कर सकते हैं।

+0

वैकल्पिक रूप से शुरुआती धागे के लिए अकेले स्टैक आकार को छोड़ दें और केवल बाद के लोगों के लिए इसे बदलें (यानी आपके द्वारा बनाए गए प्रत्येक थ्रेड के लिए स्टैक आकार सेट करने के लिए 'pthread_attr_setstack()' का उपयोग करें) – Spudd86

0

इस में ढेर आकार सेट मदद कर सकता है छोटी से छोटी यह जा सकते हैं करने के लिए कार्यक्रम (अगर वह पर्याप्त नहीं है आप चुन सकते हैं):

/* compile with: gcc -lpthread -o thread-limit thread-limit.c */ 
/* originally from: http://www.volano.com/linuxnotes.html */ 

#include <stdlib.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <string.h> 

#define MAX_THREADS 100000 
int i; 

void run(void) { 
    sleep(60 * 60); 
} 

int main(int argc, char *argv[]) { 
    int rc = 0; 
    pthread_t thread[MAX_THREADS]; 
    pthread_attr_t thread_attr; 

    pthread_attr_init(&thread_attr); 
    pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN); 

    printf("Creating threads ...\n"); 
    for (i = 0; i < MAX_THREADS && rc == 0; i++) { 
    rc = pthread_create(&(thread[i]), &thread_attr, (void *) &run, NULL); 
    if (rc == 0) { 
     pthread_detach(thread[i]); 
     if ((i + 1) % 100 == 0) 
    printf("%i threads so far ...\n", i + 1); 
    } 
    else 
    { 
     printf("Failed with return code %i creating thread %i (%s).\n", 
     rc, i + 1, strerror(rc)); 

     // can we allocate memory? 
     char *block = NULL; 
     block = malloc(65545); 
     if(block == NULL) 
     printf("Malloc failed too :(\n"); 
     else 
     printf("Malloc worked, hmmm\n"); 
    } 
    } 
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use 
    exit(0); 
} 

अतिरिक्त आप इस तरह एक फोन जोड़ सकते हैं: बस pthread_attr_setstacksize() करने के लिए कॉल के बाद pthread_attr_setguardsize(&thread_attr, 0); लेकिन फिर आप ढीला था पूरी तरह से ढेर लंघन का पता लगाने, और यह आपको केवल 4k पता स्थान और शून्य वास्तविक स्मृति बचाएगा।

0

क्या आप प्रति प्रक्रिया संभव अधिकतम थ्रेड की गणना करने के लिए सूत्र बनाने की कोशिश कर रहे हैं?

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

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/

संबंधित मुद्दे