.NET应用程序中的最大线程数?

时间:2020-03-06 14:50:25  来源:igfitidea点击:

我们可以在C应用程序中创建的最大线程数是多少?当达到此限制时会发生什么?是否会抛出某种异常?

解决方案

没有内在的限制。线程的最大数量由可用的物理资源量决定。有关详细信息,请参见Raymond Chen的这篇文章。

如果我们需要询问最大线程数是多少,可能是我们做错了什么。

[更新:只是出于兴趣:.NET线程池的默认线程数:

  • 在Framework 4.0(32位环境)中为1023
  • 在Framework 4.0(64位环境)中为32768
  • 框架3.5中的每个核心250个
  • Framework 2.0中每个内核25个

(这些数字可能会因硬件和操作系统而异)]

杰夫·里希特(Jeff Richter)通过C#在CLR中:

"使用CLR 2.0版时,最大数量
计算机中每个CPU的工作线程数量默认为25
和最大I / O数
线程默认为1000。限制1000实际上根本没有限制。"

请注意,这是基于.NET 2.0的。在.NET 3.5中,这可能已更改。

[编辑]正如@Mitch所指出的,这特定于CLR ThreadPool。如果直接创建线程,请参见@Mitch和其他注释。

米奇是对的。这取决于资源(内存)。

尽管Raymond的文章专门针对Windows线程,而不是Cthread,但逻辑适用相同(Cthread映射到Windows线程)。

但是,就像我们在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)
        {
        }
    }

在VS中的异常(当然是内存不足)中放置一个断点以查看计数器的值。当然,有很大的不同。

我们应该使用线程池(或者异步代理,后者又使用线程池),以便系统可以决定应该运行多少个线程。