在Windows上,我可以同时运行多少个线程?

43

我在另一个问题的评论中看到说我只能同时运行“这么多”个线程,我也在其他地方看到过这种说法。

作为一个线程编程新手,我该如何确定最大使用线程数?或者这是一个“无法回答”的问题?这取决于什么?硬件配置还是其他因素?

(如果有影响)使用.Net 3.5的MS Visual Studio中的VB。


更新:有没有任何软件工具可以建议使用多少线程(或任务),或者我应该编写自己的代码,不断尝试不同的数量,直到吞吐量下降?


[更新日期] 已经过去将近七年,现在我们有了一个软件推荐网站,所以我询问是否有一种工具可以帮助这个问题。


1
+1 好问题。它们每个都进行一次SOAP调用来传输一些数据并等待其返回。 - Mawg says reinstate Monica
1
当然,"返回"是异步的,所以它们并不真正等待。其他线程可以在SOAP请求(函数调用)通过HTTP发送后立即运行。 - Mawg says reinstate Monica
7个回答

20

这要取决于硬件,因为您(可能)不是使用理论计算机而是物理硬件,因此您的资源是有限的。

阅读:Windows是否对每个进程有2000个线程的限制?

此外,即使您可以运行5000多个线程,根据您的硬件配置,与10个线程等效程序相比,速度可能会慢得多。我认为您应该查看线程池


1
+1 谢谢。这给了我一些东西可以尝试去理解。您是否知道有哪些软件工具可以建议线程数量? - Mawg says reinstate Monica
2
我认为每个CPU核心使用一个线程是一个明智的选择,但这确实取决于您要解决的问题。 - Trinidad
1
+1 每个核心只有一个,模拟数百个设备将会很困难。 - Mawg says reinstate Monica
2
如果您正在使用网络设备,则所有数据都将以串行方式发送,因此我猜在那里不会有性能提升。我认为可能没有必要拥有大量线程,您可以使用一个线程来持续发送数据,另一个线程来读取结果并确定响应属于哪个请求,而不是拥有大量空闲线程一次发送数据并等待回复。 - Trinidad

17
通常情况下,真正同时运行的线程数取决于您拥有的CPU和CPU核心数(包括超线程)。也就是说,在任何给定时间,正在运行的线程数(在操作系统中)等于“核心”数。
您的应用程序可以同时运行多少个线程取决于许多因素。最好的(外行人的)数字应该是机器上的核心数,但当然这就像假装没有其他应用程序存在一样:)。
坦率地说,我会建议您在.NET/Windows中进行更多的多线程研究,因为当您没有真正扎实的理解时,往往会造成更多的“破坏”而不是好处。.NET具有线程池的概念,您需要知道如何使用它以及Windows。
在.NET 3.5/4.0中,您应该查看任务(Task Parallel Library)作为库可以更好地确定要生成多少个线程(如果有的话)。使用TPL时,线程池得到了重大改进,并且在生成线程和任务窃取等方面变得更加智能化。但是,您通常使用任务而不是线程。
这是一个复杂的领域,因此,.NET框架引入了任务,以使程序员抽象出线程,从而允许运行时聪明地处理此问题,而程序员只需说明她想要什么,而不是如何做到这一点。

1
+1 是的,我担心自己可能会带来更多的破坏而不是好处。我也会看一下任务,谢谢。 - Mawg says reinstate Monica
3
我认为区分“并发”和“并行”这两个术语是有用的(即你所说的“真正并发”)。 - skaffman

11

当运行大量任务时,一个相当不错的经验法则是运行与你的物理核心数量相同的任务。

是的,你可以运行更多的任务,但它们会等待资源(或者在线程池中的线程)和你的计算机(无论大小)由于后台/其他进程的缘故不能将所有CPU核心资源100%地分配给线程。因此,实例化的任务越多,创建的线程越多,超过实际可能的并发线程数(每个核心1个),就会出现越来越多的资源管理、排队和交换。

我们在我现在工作的地方进行了一个测试,使用病毒样式启动额外的任务,发现最佳设置与CPU数量几乎相同。按照与物理核心数量一对一的比例启动的任务需要约1分钟才能完成。如果设置为双倍CPU数量,则任务完成时间从平均1分钟增加到平均5分钟。初始化超过核心计数的任务越多,速度下降的越快。

因此,例如,如果你有8个物理核心,那么8个任务(并且使用TPL,在活动进程中实质上有8个并发线程)应该是最快的。有主线程或进程创建其他任务以及其他后台进程,但如果计算机对于你的资源利用乐趣而言相当独立,那么它们将非常少。

基于核心计数编程任务上限的好处是,当你在不同大小的计算机上部署应用程序时,它会自动调整。

为了通过编程确定这一点,我们使用

var CoreCount = System.Environment.ProcessorCount / 2;

你问为什么要除以二?因为几乎所有现代处理器都使用逻辑核心或超线程。你应该发现,如果使用逻辑计数,每个任务的总体速度以及整个过程都会显著降低。物理核心才是关键。我们找不到快速找到物理与逻辑核心的方法,但对我们的盒子进行快速调查发现这是始终如一的。你的情况可能有所不同,但这可以让你快速上手。


8

每个线程都会消耗更多的内存(内核栈、线程环境块、线程本地、堆栈等)。据我所知,在Windows中没有明确的限制,因此约束将是内存(可能是每个线程的堆栈)。

在Linux中,线程更像进程(具有共享内存),您受到以下约束:

cat /proc/sys/kernel/threads-max

2

这在很大程度上取决于机器——CPU和内存是主要的限制因素(尽管操作系统的限制可能也存在)。

关于.NET,线程池配置也很重要。


2

根据我的经验,在使用线程时,对于 CPU 密集型进程增加性能的一个好的经验法则是使用与核心数量相等的线程,但在超线程系统中,应该使用两倍的核心数。另一个可以得出的经验法则是针对 I/O 密集型进程。这个规则是将每个核心的线程数增加到四倍,但在超线程系统中,则可以将每个核心的线程数增加到四倍。


Lolx - 当我第一次发布时,还没有多核CPU这种东西:-) 感谢建议 +1 - Mawg says reinstate Monica

-1
我能够在我的旧CPU(2005年)上同时运行4个线程,使用EVGA的CPU烧录程序,在我的CPU蜂鸣器响起之前(在BIOS菜单中编程),意味着我超过了90℃。请记住,我们正在谈论同时工作的数据线程。一个很好的例子就是同时打开多个程序。但总的来说,这取决于你的CPU在多任务处理方面的表现如何(换句话说,能否处理许多活动线程)。测试的安全方法是下载“ocscanner(由EVGA提供)”和“CPU温度计”,在OC Scanner中使用CPU Burner进行测试,确保您的温度不会超过90℃(或任何您感到安全的温度),并查看您当前运行的线程数。从2个线程开始,等待3-5分钟,同时观察CPU温度,添加另一个线程,重复此过程。(不要冒险!)(如果CPU温度计无法检测到您的温度,请勿尝试!)

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