.NET ऐप में अधिकतम कितने थ्रेड हैं?


140

C # एप्लिकेशन में आप अधिकतम कितने थ्रेड बना सकते हैं? और जब आप इस सीमा तक पहुँच जाते हैं तो क्या होता है? क्या किसी तरह का अपवाद फेंका गया है?


यदि आप x64 VM या x86 VM पर चल रहे हैं, तो उत्तर अलग-अलग होगा
ब्रायन आर। बॉन्डी

मेरी स्थिति में यह x86 है, लेकिन क्या किसी और की ज़रूरत पड़ने पर आप दोनों के लिए जवाब दे सकते हैं?

जवाबों:


145

कोई अंतर्निहित सीमा नहीं है। थ्रेड्स की अधिकतम संख्या उपलब्ध भौतिक संसाधनों की मात्रा से निर्धारित होती है। बारीकियों के लिए रेमंड चेन का यह लेख देखें ।

यदि आपको यह पूछने की आवश्यकता है कि थ्रेड्स की अधिकतम संख्या क्या है, तो आप शायद कुछ गलत कर रहे हैं।

[ अपडेट : बस ब्याज से बाहर: .NET थ्रेड पूल डिफ़ॉल्ट थ्रेड्स की संख्या:

  • फ्रेमवर्क 4.0 में 1023 (32-बिट वातावरण)
  • 32767 फ्रेमवर्क 4.0 (64-बिट वातावरण) में
  • फ्रेमवर्क 3.5 में 250 प्रति कोर
  • फ्रेमवर्क 2.0 में 25 प्रति कोर

(ये संख्या हार्डवेयर और OS के आधार पर भिन्न हो सकती है)]


13
आपने यह कैसे पता लगाया? क्या आप जानते हैं कि .NET 4.5 क्या है या 5.0 क्या होगा?
goodguys_activate

3
आप इस कोड का उपयोग गिनती प्राप्त करने के लिए कर सकते हैं: इंट वर्करट्रेड्स; int समापनपार्टीट्स; ThreadPool.GetMaxThreads (वर्कर आउट थ्रेड, आउट पूर्णपार्ट थ्रेड्स);
17

1
@ मिचैट मैं खुद को आश्चर्यचकित कर रहा था, क्योंकि जुड़ा हुआ लेख .NET पर चर्चा नहीं करता, लेकिन सादे 'ol C.
pqsk

1
@ लौकोमो: यदि आप एक धागा नहीं बना सकते हैं, तो आप शायद स्मृति से बाहर चले गए हैं! मैंने इसकी कोशिश नहीं की है, लेकिन मैं मान रहा हूं कि एक स्मृति अपवाद को फेंक दिया जाएगा ....?
मिच गेहूं

1
@Liam लिंक को अब ठीक किया जाना चाहिए।
यूजीन कोमिसेंको

26

मिच सही है। यह संसाधनों (मेमोरी) पर निर्भर करता है।

यद्यपि रेमंड का लेख विंडोज थ्रेड्स के लिए समर्पित है, सी # थ्रेड्स के लिए नहीं, तर्क एक ही लागू होता है (सी # थ्रेड्स विंडोज थ्रेड्स में मैप किए जाते हैं)।

हालाँकि, जैसा कि हम C # में हैं, यदि हम पूरी तरह से सटीक होना चाहते हैं, तो हमें "प्रारंभ" और "गैर-आरंभ" के बीच अंतर करने की आवश्यकता है। केवल थ्रेड्स वास्तव में स्टैक स्पेस आरक्षित करते हैं (जैसा कि हम उम्मीद कर सकते हैं)। गैर शुरू किए गए धागे केवल एक थ्रेड ऑब्जेक्ट द्वारा आवश्यक जानकारी आवंटित करते हैं (यदि आप वास्तविक सदस्यों में रुचि रखते हैं तो रिफ्लेक्टर का उपयोग कर सकते हैं)।

आप वास्तव में इसे अपने लिए परख सकते हैं, तुलना करें:

    static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                newThread.Start();
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

साथ में:

   static void DummyCall()
    {
        Thread.Sleep(1000000000);
    }

    static void Main(string[] args)
    {
        int count = 0;
        var threadList = new List<Thread>();
        try
        {
            while (true)
            {
                Thread newThread = new Thread(new ThreadStart(DummyCall), 1024);
                threadList.Add(newThread);
                count++;
            }
        }
        catch (Exception ex)
        {
        }
    }

काउंटर के मूल्य को देखने के लिए वीएस में अपवाद (स्मृति से बाहर, निश्चित रूप से) में एक ब्रेकपॉइंट डालें। बहुत महत्वपूर्ण अंतर है, निश्चित रूप से।


9

मैंने c # कंसोल के साथ 64 बिट सिस्टम पर एक परीक्षण किया, अपवाद 2949 थ्रेड का उपयोग करते हुए, मेमोरी से बाहर का प्रकार है।

मुझे लगता है कि हमें थ्रेडिंग पूल का उपयोग करना चाहिए, जो मैं करता हूं, लेकिन यह उत्तर मुख्य प्रश्न के जवाब में है;)


6

आपको थ्रेड पूल का उपयोग करना चाहिए (या async डेलगेट्स, जो बदले में थ्रेड पूल का उपयोग करते हैं) ताकि सिस्टम यह तय कर सके कि कितने थ्रेड चलना चाहिए।


इस सवाल का जवाब है प्रणाली तय करने देने के लिए।
इयान बॉयड

@ इयान: मैंने आपको नीचा दिखाया क्योंकि उसी उत्तरदाता को नौ महीने पहले दिया गया था।
जॉन साउन्डर्स

11
संपर्क। मैं किसी के जवाब के रूप में थ्रेड पूल का कोई उल्लेख नहीं देखता।
इयान बॉयड

4

C # के माध्यम से CLR में जेफ रिक्टर:

"सीएलआर के संस्करण 2.0 के साथ, मशीन में 25 प्रति सीपीयू के लिए डिफ़ॉल्ट रूप से कार्यकर्ता थ्रेड्स की अधिकतम संख्या और I / O थ्रेड्स की अधिकतम संख्या 1000 तक चूक जाती है। 1000 की सीमा प्रभावी रूप से कोई सीमा नहीं है।"

ध्यान दें कि यह .NET 2.0 पर आधारित है। यह .NET 3.5 में परिवर्तित हो सकता है।

[संपादित करें] जैसा कि @ मिच ने बताया, यह सीएलआर थ्रेडपूल के लिए विशिष्ट है। यदि आप थ्रेड बना रहे हैं तो सीधे @ मिच और अन्य टिप्पणियां देखें।


आप .NET 3.5 के बारे में अपनी टिप्पणी में CLR 2.0 और .NET 2.0 को भ्रमित कर रहे हैं।
bzlm

जहाँ तक मुझे पता है .NET 2.0 के लिए SP1 (.NET 3.5 का हिस्सा) ने थ्रेड पूल के लिए वर्कर थ्रेड्स को डिफ़ॉल्ट रूप से 250 प्रति सीपीयू / कोर में बदल दिया।
माइकल दमातोव

0

आप इस स्निप्ड कोड का उपयोग करके इसका परीक्षण कर सकते हैं :

private static void Main(string[] args)
{
   int threadCount = 0;
   try
   {
      for (int i = 0; i < int.MaxValue; i ++)
      {
         new Thread(() => Thread.Sleep(Timeout.Infinite)).Start();
         threadCount ++;
      }
   }
   catch
   {
      Console.WriteLine(threadCount);
      Console.ReadKey(true);
   }
}

आवेदन के 32-बिट और 64-बिट मोड से सावधान रहें।


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