在多核处理器上启动多个线程时,是否保证它们可以由不同的内核处理?


24

我有一个具有4个核心的Pentium核心i5处理器。如果我在C#控制台程序中执行此操作

var t1 = new Thread(Thread1);
var t2 = new Thread(Thread2);
t1.Start();
t2.Start();

保证t1和t2线程在单独的内核上运行?


1
假设C#运行时使用等效的本机系统调用生成另一个线程(因此是真正的并行;并非所有情况都如此,例如臭名昭​​著的CPython的Global Interpreter Lock),这将完全取决于操作系统的进程/任务调度程序。但是,通常,如果您假设代码确实是线程安全的,t1并且t2可以在任意时间以任意顺序执行代码(例如,可能在某些模型中于代码t2开始)。 t1
突破

2
我不知道有奔腾i5处理器。也许您是说Core i5?挑剔 我知道:D
JosephGarrone 2013年

Answers:


18

您无法在.Net中保证两个Threads在两个单独的内核上运行。实际上,您也不能保证一个Thread只能在一个内核(!)上运行

这是因为托管线程与OS线程不同 -一个托管线程可能使用多个OS线程来支持它。在C#中,您只能直接处理Managed Threads (至少不使用p / invoke调用WinAPI线程函数,这是您永远都不应这样做的)

但是,.Net和Windows线程调度程序非常擅长于它们的工作-它们不会在单个内核上运行两个线程,而第二个内核完全处于空闲状态。因此,总的来说,您无需担心。


在实践中,净Thread小号 OS线程。但这不是为什么不能保证单个线程将始终在同一内核上执行的原因。
svick

2
@svick:实际上,在x86上是这样。但是,该标准明确规定您不能依赖此行为,因此将来可能会更改。实际上,在其他版本的.Net CLR(例如XBox 360)上并非如此。
BlueRaja-Danny Pflughoeft13年

@BlueRaja-问题是关于我们正在谈论的CLR版本。您可以通过使用异步线程来保证某些东西会存在于两个独立的内核上,因为这意味着它们将彼此异步发生。当前的示例代码在技术上是一个同步调用。当然,操作系统将决定使用哪些内核。
Ramhound

@Ramhound “您可以通过使用异步线程来保证两个单独的内核中将存在某些东西” -这是错误的。该async关键字(这是我认为你说的是,作为“异步线程”是多余的)是使用一个公正的语法糖BackgroundWorker线程,这是像任何其他.NET线程-你不能保证它是否会在运行是否分离核心。
BlueRaja-Danny Pflughoeft13年

@BlueRaja-如果启动了两个异步线程,只要有2个CPU内核,它们就会同时运行。如果只有一个,则操作系统将安排每个线程获得优先级并运行的时间,并且会发生典型的单线程崩溃情况。这就是我被教导CPU如何处理多线程的方式。
Ramhound

15

不,操作系统和CPU将决定运行什么以及何时运行。在您显示的简单示例中,排除了其他任务,是的,这些任务很可能会在单独的内核上并行运行,但是很少有这种情况的保证。

您可以使用线程亲缘关系来尝试控制对给定线程的核心分配。

还应考虑根据哪些线程应该完全并行以及哪些线程可以等待来安排堆栈的优先级


1
我还想补充一点,使用虚拟化技术,您的程序和硬件之间还有另一层。操作系统提供给应用程序的内容可能在物理上不准确。
Keltari 2013年

1
这些是WinAPI函数,适用于OS线程,而不适用于托管线程。绝对不要从C#调用它们,因为它们可能会严重干扰.Net线程计划程序。
BlueRaja-Danny Pflughoeft13年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.