例如,我想知道一个C#线程是否耗尽了一个CPU线程:
如果您有一个有八个线程的CPU,例如: 4790k并且启动了两个新的C#线程,那么您会失去两个线程吗?比如8-2= 6?
发布于 2015-01-20 05:28:30
线程不是核心。在您给定的情况下,您的计算机有8个可以处理线程的内核(4个物理核和4个逻辑核)。
计算机一次处理数百个线程,并在它们之间切换得非常快。如果您在您的Thread应用程序中创建了一个C#类,它将创建一个新线程,该线程将在您的CPU上的任何核心上执行。您拥有的内核越多,计算机运行的速度就越快,因为它可以一次处理更多的线程(在计算机的速度中还有其他因素在发挥作用,而不仅仅是有多少个内核)。
发布于 2015-01-20 05:42:23
如果我没有记错,虚拟机(CLR)可以自由地做它想做的任何事情。例如,有些称为绿色线程的实现不一定将托管线程映射到本机线程。但是,当然,在桌面x86上的x86中,我们所知道的实现试图真正映射到系统线程。
现在这是一个层,但它仍然没有提到CPU。操作系统调度程序将允许硬件线程(由于超线程而虚拟化)执行本机线程时,它决定它是可以的。
有一种被称为“过度提交”的东西,即当太多本机线程想要运行时(在操作系统的调度程序ready queue中),但是CPU只有那么多线程可使用,因此有些线程仍然在等待,直到它们的权重(操作系统调度器的内部度量之一)决定该轮到它们了。
您可以查看此文档以获得更多信息:https://www.kernel.org/doc/Documentation/scheduler/sched-design-CFS.txt
实际上,在讨论中,有用的MSDN页面https://learn.microsoft.com/en-us/dotnet/standard/threading/managed-and-unmanaged-threading-in-windows解释说:
操作系统ThreadId与托管线程没有固定关系,因为非托管主机可以控制托管线程和非托管线程之间的关系。具体来说,复杂的主机可以使用Fiber对同一个操作系统线程调度许多托管线程,或者在不同的操作系统线程之间移动托管线程。
出于非常有趣的原因。当然,其中之一就是虚拟机实现的自由。但另一个问题是在本机/管理的屏障之间传递的自由,具有很大的灵活性,如本页所解释的那样。特别要注意的是,本机线程可以向后进入托管应用领域,并看到虚拟机自动分配托管线程对象。此管理使用线程id散列进行维护。疯狂的东西:)
实际上,我们可以在页面https://learn.microsoft.com/en-us/archive/msdn-magazine/2006/august/clr-inside-out-clr-hosting-apis#S3上看到CLR具有可配置的线程API映射。非常灵活,这确实证明了不能肯定地说一个C#线程==一个本机线程。
发布于 2015-01-20 05:49:01
作为JRLambert已经触及,可以在同一个内核上运行多个线程。
当您在.NET应用程序中生成新线程时,实际上并不是多任务。现在发生的是时间分割。您的CPU将不断地在不同的线程之间切换,让它们看起来像是在并行工作。但是,在任何给定的时间,核心只能在单个线程上工作。
例如,在实现任务并行库(TPL)时,当您的机器有多个内核时,您将看到,与生成新线程相比,内核得到的工作负载分配得更均匀。微软确实在TPL方面做了一些很棒的工作,简化了多线程异步环境,而不必像过去那样对线程池和同步原语做大量的工作。
看看这个YouTube视频。他很好地描述了时间分割和多任务处理。
如果你还不熟悉TPL,Sacha有一个非常棒的系列论代码工程。
https://stackoverflow.com/questions/28038307
复制相似问题