我们真的需要所有这1000个线程运行吗?

Dav*_*vid 12 multithreading

在Windows 8中使用花哨的新任务管理器我发现了一些令我惊讶的东西,当前使用/正在运行的线程大约1k.

因为我刚刚接触过多线程软件和游戏背后的教程和理论.我假设如果你想从你的软件中获得最佳性能,那么当有工作要做时,你应该每个逻辑处理器至少有一个线程.由于该处理器否则将"未使用".

但是看到我已经运行了大约1000个线程,所有处理器都不会在处理某些事情吗?

为什么多线程如果处理能力已被其他50个左右的进程使用?管理所有这1000个线程不管cpu吗?为什么我作为程序员处理线程而不是操作系统?如果它给每个进程一个线程,我的软件是不是仍然是"multhithreaded"?

使用更多线程只是一种优先处理流程的更好的方式吗?

Jak*_*lås 24

我会说,可能不是.虽然这个问题有点夸夸其谈,但请看看Jeffrey Richter撰写的这篇文章/书摘录,停止疯狂(从书籍CLR到C#).它只讨论你问的那些事情.

如果我们关心的只是原始性能,那么任何机器上的最佳线程数与该机器上的CPU数量相同.[...]所有线程仍然有内核对象,内核模式堆栈和分配给它们的其他资源.由于它们便宜而不得不停止创造线索的趋势; 线程并不便宜 - 相反,它们很昂贵,所以明智地使用它们.

我强烈推荐这本书.非常值得一读前后,虽然它相当大,约900页.

虽然多线程是一个非常复杂的主题,并且只能在几行中轻松回答,但它高度依赖于您要实现的目标.与往常一样,它取决于您必须测量/评估/优化任何解决方案以获得最佳性能.但是,通常情况下,经常抛出线程可能不是一个好主意.作为旁注,托管线程分配1 MB堆栈内存,这意味着在.NET应用程序中创建(并保持)线程可能非常浪费.

此外,仅仅因为一个胎面存在不能意味着它会消耗一个完整的核心.它可能会做一些工作,但它也可能闲置等待一些工作(最可能的情况,否则你的整体CPU消耗将不断接近100而不是0).他们不过消耗,或者更正确,浪费系统资源.

虽然引入了许多技术以使它们更易于使用(各种并行框架等),但引入线程会给应用程序增加大量额外的复杂性.然而,潜在的复杂性仍然存在,有时会被认为是无害的,但总是准备爆发其真实性质(时序问题,死锁,调试复杂性等).

简而言之,您可能会说,"除非您有理由,否则不要使用多个线程".
即使这样,t(h)也会轻微阅读.


Lor*_*tté 8

我喜欢Jokob的回答,我觉得大部分要点已经完成了:

  • 1k个线程(全局)并不意味着它们完全运行:它们可能全都坐在等待
  • 一般而言,考虑系统中的全局线程数是非常误导的(请参阅下面的说明)
  • 线程(不仅)用于并行编程:它们用于需要多行执行的情况(例如,当您阻止等待网络应答时,但仍需要更新UI并保持响应,或者当您在同一过程中执行低优先级任务(拼写检查,代码检查......)时,...).毕竟,线程存在并且在多核CPU之前很久就有用了!
  • 然而,现在我们经常看到"疯狂":太多线程.这不是新的:早期网络(web?)服务器的第一种情况之一:每个连接一个线程(!).愚蠢,浪费.我们继续,我们现在使用线程池(以及更精致的东西,如I/O完成端口)和(最近)异步编程.

但是,即使在线程池的情况下,线程数也是每个进程(除非你使用系统线程池,从Windows2000开始提供); 因此,如果你有50个进程,每个进程都希望从4核系统中获得最大的优势,那么你拥有全局合理数量的200个线程(并且通常,线程池的最佳核心数量大约为2X,以便采用I/O块和等等).

这是很自然的,你必须考虑每个进程,而不是操作系统范围.想想如果对所有进程使用具有硬限制的集中式线程池会发生什么.假设一个应用程序占用了所有这些:您有什么选择?不,你不能有一个严格的操作系统范围限制.每个应用程序基本上都是独立的.这是由"现代"(1990年代)操作系统强制执行的模型,它基于隔离进程和虚拟,私有地址空间,如NT和Linux:你在操作系统中是独一无二的,不应该关心其他操作系统(有时这是强烈的强制执行,就像记忆一样)