Windows Server 2003 中线程的最大数量是多少?

32

有人知道吗?还有一个更大的问题是当你遇到这个最大值时会发生什么?这个最大值在其他Windows操作系统(如Vista、XP等)中是否相同?


我猜测限制因素并不是线程数,而是内存使用量。 - zsharp
8个回答

37

首先建议阅读以下内容:http://blogs.msdn.com/oldnewthing/archive/2007/03/01/1775759.aspx

然后再看http://blogs.msdn.com/oldnewthing/archive/2005/07/29/444912.aspx

总结一下,线程数量受限于堆栈空间(必须是连续块),由于每个线程都会使用这些散布的堆栈空间,因此你很快就会耗尽连续的块。在64位机器和操作系统上,这不会成为太大问题。

存在缓解策略,但只能适用于每个线程使用的堆栈空间较少。

作为一个大概指南:

  • 创建十个几乎肯定可行
  • 在当前服务器和台式机硬件上创建几百个可能有风险
  • 创建数千个几乎肯定会失败。

通常情况下你不需要创建超过十个线程(如果您确实需要,那么您应该已经知道这些信息)。


提前创建它们并在内存不被分段时进行池化以供后续使用也应该有所帮助。 - Marco van de Voort
https://blogs.msdn.microsoft.com/tmarq/2007/07/20/asp-net-thread-usage-on-iis-7-5-iis-7-0-and-iis-6-0/ - hod caspi

26

当问起这类问题时,我听到的最好的答案是:

这不重要,如果你发现这很重要,那么你需要重新考虑自己在做什么,使其变得不重要。


6
当有数百个小线程在浮动时,线程会变得自我矛盾(和低效)。使用线程池,您就不必担心了。 - paxdiablo
1
+1 评论。让我的一天都变得美好了。而且当涉及到线程时,这确实是正确的。 - Kornelije Petak
我将在骑士着陆上运行Windows。因此,现在具有256-288个线程非常重要。 - user1649948

16

请注意,如果您担心达到这个限制,请仔细检查您的设计!

回答您“更重要的问题”的是OutOfMemoryException。

下面是一些代码来找出此限制,虽然它可能取决于可用内存。 我们很想看到其他操作系统/ CPU / mem结果。

请随意编辑并添加您的机器:

  • Windows 7,VS2008,双核,2GB内存:1,465,然后崩溃并显示OutOfMemoryException

    int i = 0;
    try
    {
        while (true)
        {
            new Thread(new ThreadStart(() => Thread.Sleep(int.MaxValue))).Start();
            i++;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(i);
        Console.WriteLine(ex.ToString());
    }

1
对于“如果你必须问,那么你做错了什么”的观点表示赞同! - Greg Beech
为什么你要将这个设为社区 wiki?这是一个好答案(我给你点赞了);你应该得到相应的贡献。 - John Rudy
社区维基是因为我不在乎声望的事情,而且它使得其他人更容易添加他们的结果。 - TheSoftwareJedi

3

默认堆栈大小为1MB,32位Windows操作系统下分配给进程的用户模式地址空间大约为2GB。这允许每个进程拥有大约2000个线程(2000 * 1MB = 2GB)。对于64位系统,实际上不存在这样的问题。


2
请阅读ShuggyCoUk's answer所指向的Raymond Chen博客文章。
但要特别注意这一点:
引用: “但每当有人问‘一个进程最多可以创建多少个线程?’时,真正的问题是‘为什么你要创建这么多线程,以至于这成为一个问题?’” “‘一个客户端一个线程’的模型众所周知无法扩展到超过十几个客户端。如果您将同时处理超过那么多客户端,应该转向一种模型,即不是将线程专门分配给一个客户端,而是分配一个对象。(有一天我会思考线程和对象之间的双重性。)Windows提供了I/O完成端口和线程池来帮助您从基于线程的模型转换为基于工作项的模型。”

1

1

如果你被卡在一个使用大量线程并需要扩展的现有设计中,你也可以考虑纤程:

http://msdn.microsoft.com/en-us/library/ms682661%28v=vs.85%29.aspx

它可以避免您进行全面的重新设计。

Indy曾考虑在Indy 10中实现它,但由于似乎.NET冒险占用了大部分时间,因此从未发生。


ShuggyCoUk在他的第二个OldNewThing链接中提到了关于纤程的以下内容:请注意,纤程在这里并没有太大帮助,因为纤程具有堆栈,并且几乎所有时间都是由堆栈所需的地址空间成为限制因素。 - foraidt
ShuggyCoUk的链接并不是最终解决方案。我认为它更像是一个额外的规模扩展,完整的线程无法实现。但正如所说,这些知识来自于64位代表alpha的时代的过时讨论。 - Marco van de Voort

1
据我所知,整个线程模型自Win2K以来应该没有太大变化。
从本质上讲,并没有真正的线程限制,而更多的是进程堆栈空间的限制。有关此问题的更多详细信息,请参阅Raymond Chen的线程限制深入解释

但是每当有人问“一个进程可以创建的最大线程数是多少?”这个问题时,真正需要提出的问题是,“为什么要创建这么多线程,以至于这成为一个问题?” - TheSoftwareJedi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接