我对 C# 线程池的理解是否正确?

Is my understanding of the C# threadpool correct?

我正在阅读 Essential C# 5.0 上面写着,

The thread pool also assumes that all the work will be relatively short-running (that is, consuming milliseconds or seconds of processor time, not hours or days). By making this assumption, it can ensure that each processor is working full out on a task, and not inefficiently time slicing multiple tasks. The thread pool attempts to prevent excessive time slicing by ensuring that thread creation is "throttled" and so that no one processor is "oversubscrived" with too many threads.

我一直认为多线程的好处之一是时间分片。

如果你有 >1 个处理器,那么你可以并发 运行 个线程并实现真正的多线程。但除非是这种情况,否则您必须对具有多个线程的应用程序求助于时间切片,对吗?

所以,如果C#中的ThreadPool没有时间片,那么,

一个。这是否意味着线程池 用于绕过创建新线程的开销?

b。这是否意味着 ThreadPool 不能同时 运行 多个线程,除非处理器有多个内核,其中每个内核可以 运行 一个进程?

你提到的引用是指线程池在其已创建的所有线程都已分配给任务时创建新线程的速率。新线程创建速率受到限制(新任务排队)以避免在线程池上放置大量任务时创建许多线程(并淹没 CPU)。

当前算法确实为每个 CPU 核心创建了很多线程,但是创建它们的速度相对较慢,希望它已经创建的线程能够快速满足当前积压的任务,并且不需要添加线程。

.NET 线程池将为每个核心创建多个线程,但具有启发式算法,可在执行最大工作量的同时保持尽可能低的线程数。

这意味着如果您的代码是 CPU 绑定的,您最终可能会得到每个核心一个线程。如果您的代码是 I/O-bound 并且阻塞或排队大量工作项,您最终可能会在每个核心有很多线程。

不仅仅是线程创建是昂贵的:数百个线程之间的上下文切换会占用大量时间,您宁愿花在 运行 自己的代码上。更多线程几乎永远不会更好。

问。这是否意味着 ThreadPool 仅用于绕过创建新线程的开销?

一个。不。创建线程通常不是问题。目标是让您的 CPU 以 100% 的速度工作,同时使用尽可能少的并发执行线程。较少的线程数将避免过多的上下文切换,并改善整体执行时间。

问。这是否意味着 ThreadPool 不能同时 运行 多个线程,除非处理器有多个内核,其中每个内核可以 运行 一个进程?

一个。它 运行 多个线程同时进行。理想情况下,每个核心 运行 恰好是一个 CPU 密集型任务,在这种情况下,您 CPU 以 100%

工作