在Windows 8中使用花哨的新任务管理器我注意到一些令我惊讶的东西,当前使用/正在运行的线程大约1k。
因为我刚刚接触过多线程软件和游戏背后的教程和理论。我假设如果你想从你的软件中获得最佳性能,那么当有工作要做时,你应该每个逻辑处理器至少有一个线程。由于该处理器否则将“未使用”。
但是看到我已经运行了大约1000个线程,并不是所有处理器都在处理某些事情吗?
为什么多线程如果处理能力已被其他50个左右的进程使用? 管理所有这1000个线程不管cpu吗? 为什么我作为程序员处理线程而不是操作系统?如果它给每个进程一个线程,我的软件是不是仍然是“multhithreaded”?。
使用更多线程只是确定流程优先级的更好方式吗?
答案 0 :(得分:24)
我会说,可能不是。虽然这个问题有点夸夸其谈,但请看看Jeffrey Richter撰写的这篇文章/书摘录,Stop the madness(来自书籍CLR via C#)。它只讨论你提出的问题。
如果我们所关心的只是原始性能,那么就是最佳线程数 在任何计算机上都与该计算机上的CPU数相同。 [...]所有线程仍然有内核对象,内核模式堆栈, 和分配给他们的其他资源。这种创造线索的趋势因为它们而无所事事 便宜必须停止;线程并不便宜 - 相反,它们很昂贵,所以明智地使用它们。
我强烈推荐那本书。非常值得一读前后,虽然它相当大,约900页。
多线程虽然是非常复杂的主题,但只能在几行中轻松回答,它高度依赖于您要实现的目标。与往常一样,它取决于您必须测量/评估/优化任何解决方案以获得最佳性能。但是,通常情况下,经常抛出线程可能不是一个好主意。作为旁注,托管线程分配1 MB堆栈内存,这意味着在.NET应用程序中创建(并保留)线程可能非常浪费。
另外,仅仅因为存在 可以做一些工作,但它也可能处于空闲状态并等待一些工作(最可能的情况,否则你的整体CPU消耗将不断接近100而不是0)。然而,他们做会消耗或更准确地浪费系统资源。
引入线程会给应用程序增加大量额外的复杂性,即使引入了许多技术以使它们更易于使用(各种并行框架等)。然而,潜在的复杂性仍然存在,有时会构成无害的,但总是准备突然发现它的真实性质(时序问题,死锁,调试复杂性等)。
简而言之,你可能会说,“除非你有理由,否则不要使用多线程。” 即使这样,t(h)也会轻易阅读。
答案 1 :(得分:8)
我喜欢Jokob的回答,我觉得大部分要点已经完成了:
但是,即使在线程池的情况下,线程数也是每个进程(除非你使用系统线程池,从Windows2000开始提供);因此,如果您有50个进程,每个进程都希望从4核系统中获得最大的优势,那么您可以在全局范围内拥有合理数量的200个线程(并且通常,线程池的最佳核心数量大约为2X,以获取I / O块和等等)。
这很自然,你必须考虑每个进程,而不是OS范围。想想如果对所有进程使用具有硬限制的集中式线程池会发生什么。假设一个应用程序占用了所有这些:您有什么选择?不,你不能有一个严格的操作系统范围限制。每个应用程序基本上都是独立的。这是由“现代”(1990年代)操作系统强制执行的模型,它基于隔离进程和虚拟,私有地址空间,如NT和Linux:你在操作系统中是独一无二的,不应该关心其他操作系统(有时这是强烈的强制执行,就像记忆一样)
答案 2 :(得分:0)
简单来说,操作系统使所有应用程序都感觉它们在自己的机器(计算机)上运行。例如,32位应用程序理论上具有4GB内存,而物理计算机具有2GB内存。操作系统正在使用时间共享多路复用等技术来提供此功能。使用此机制,您可以观察此1K线程。 (我在连接了28个用户的终端服务器上看到了72K。)由于创建线程是昂贵的程序员一次创建线程,当任务通过互斥,信号量等机制完成时,它们会让他们睡眠......
那是因为你看到很多线程和1%的CPU使用率。如果要查看线程使用了多少CPU资源,请检查线程或应用程序的CPU时间。这为发生的事情提供了更多线索。