线程池最大线程数

35

我在使用 .NET 4 中的 ThreadPool 时遇到了一些问题。

我读到 .NET 默认情况下每个处理器有 25 个线程的限制,但是根据来自stackoverflow和其他地方的论坛帖子,我可以使用以下代码增加这个限制。

void SetThreads(int threads)
{
    ThreadPool.SetMaxThreads(threads, threads);
    ThreadPool.SetMinThreads(threads, threads);
}

然而,当我将上述内容设置为一些任意高的数字,例如2000,并且排队约1000个项目时,我仍然只有大约33个线程在运行(.NET CLR占用了约5个线程),并且ThreadPool.GetAvailableThreads()返回1971个剩余线程。

为什么上面的代码不起作用?


1
你是如何在线程池中排队任务的?展示你的测试代码会非常有帮助。 - Paul Turner
你的问题是你应该运行少于33个线程,而不是更多。 - H H
@Henk Holterman,这不是一个大型应用程序-这是一个我制作的快速的HTTP负载生成器,旨在尝试使用一堆请求加载本地Web服务器。不幸的是,效果并不好。 - foxy
使用任务和/或APM作为负载生成器。 - H H
任务不是在内部使用线程池吗?我从来没有使用过APM,所以我会看一下它。我刚做了一些研究,看起来APM也使用线程池? - foxy
APM 使用 IO 端口(查看您方法中的第二个参数)。TPL 对 APM 有一些支持。是的,这都是线程池,重要的是您如何使用它。 - H H
3个回答

100
首先,你对默认设置的“了解”是不正确的。从.NET 1.1开始,每个处理器的线程限制为25条。它在.NET 2中增加了现在

从 .NET Framework 版本 4 开始,进程的线程池默认大小取决于多种因素,如虚拟地址空间的大小。进程可以调用 GetMaxThreads 方法来确定数量。

但是,还有其他因素在起作用:线程池并不会在所有情况下立即创建新线程。为了应对短时间内大量小任务的情况,它限制了创建新线程的速度。如果存在未完成的任务,每0.5秒它将创建一个线程,直到达到最大线程数。尽管我无法立刻找到相关文档记录这个数字,但我强烈怀疑这就是你看到的情况。尝试排队大量任务,然后随时间监视线程数量。

1
这应该是被接受的答案,它清楚地解释了freedompeace正在经历什么。 - Fayilt
1
那就是答案!我注意到那个奇怪的半秒钟,有时一秒钟什么也没有做。我有等待任务和其他等待启动的任务,所有东西都很慢。我需要大约10个线程来完成我的工作。将ThreadPool.SetMinThreads设置为20(默认值为8)个工作线程立即解决了我的问题!由于我以后还需要这些线程,因此我不会再降低最小值。 - ygoe

8

1
我排队了大约50k个任务,并将线程池的最小和最大线程设置为20k,但只使用了大约25个线程。这是预期的吗? - foxy
任何任务是否完成或进入等待状态了?由管理器创建线程是可以的。在某些机器上,最好不要有太多线程,因为线程会遭受线程饥饿的困扰。 - Emond

3
首先请查看此链接,特别是这段话:

如果公共语言运行时(CLR)由Internet信息服务(IIS)或SQL Server等托管,则主机可以限制或防止更改线程池大小。

然后您应该检查ThreadPool.SetMaxThreads(threads, threads)方法的返回值。也许它返回false

谢谢,我正在使用 Windows 7 上的 .NET 4。 - foxy

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