在线程池外创建线程有什么好处?

What is the advantage of creating a thread outside threadpool?

好的,所以我想知道当我使用 TaskCreationOptions.LongRunning 时会发生什么。通过 this 回答,我了解到对于长 运行 任务,我应该使用此选项,因为它会在线程池 之外创建一个线程

酷。但是,当我在线程池之外创建一个线程时,我会得到什么好处呢?什么时候做和避免它?

what advantage would I get when I create a thread outside threadpool?

线程池,顾名思义,是分配一次并在整个过程中重复使用的线程池,以节省分配线程所需的时间和资源。池本身会根据需要调整大小。如果您排队的工作比池中存在的实际工作人员多,它将以 500 毫秒的间隔分配更多线程,一次一个(这样做是为了避免在现有线程可能已经完成执行并可以服务请求的情况下同时分配多个线程)。如果在线程池上执行许多长 运行 操作,它会导致 "thread starvation",这意味着委托将开始排队并且 运行 只有在线程释放后才会发生。这就是为什么您要避免大量线程使用线程池线程进行冗长的工作。

The Managed Thread-Pool docs也有一个关于这个问题的部分:

There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:

  • You require a foreground thread.
  • You require a thread to have a particular priority.
  • You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large
    number of blocked thread pool threads might prevent tasks from
    starting.
  • You need to place threads into a single-threaded apartment. All ThreadPool threads are in the multithreaded apartment.
  • You need to have a stable identity associated with the thread, or to dedicate a thread to a task.

更多信息,请参阅:

"Long running"可以很好量化,一个线程超过半秒就是运行宁长。这是现代机器上堆积如山的处理器指令,你必须每秒消耗掉 50 亿条指令。很难以建设性的方式做到这一点,除非你计算 Pi 的值到小数点后的几千位。

实际线程只有在不燃烧核心但等待很多时才能花费那么长时间。总是在 I/O 完成时,例如从磁盘、网络、数据库服务器读取数据。这通常也是您首先开始考虑使用线程的原因。

线程池有一个 "manager"。它确定何时允许线程池线程启动。当您在程序中启动它时,它不会立即发生。管理器试图将 运行ning 线程数限制为您拥有的 CPU 内核数。这样效率更高,太多活动线程之间的上下文切换是昂贵的。还有一个好的油门,防止你的程序一下子消耗太多资源。

但是线程池管理器有一个管理器非常普遍的问题,它对正在发生的事情了解得不够多。就像我的经理不知道我在 whosebug.com 偷懒一样,tp 经理不知道线程正在等待某事而不是 实际上 执行有用工作。没有这些知识,它就无法做出正确的决定。一个需要大量等待的线程应该被忽略,另一个线程应该被允许 运行 代替它。实际做真正的工作。

就像你告诉你的经理你去度假,这样他就不会完成任何工作,你告诉线程池经理 LongRunning 同样的事情。

请注意,这并不像这个答案中听起来的那样糟糕。特别是 .NET 4.0 聘请了一位新经理,他在确定 运行ning 线程的最佳数量方面更加聪明。它通过反馈循环来实现,收集数据以发现活动线程是否真正完成了工作。并相应地调整最佳值。这种方法的唯一问题是关闭反馈回路时的常见问题,您必须使其变慢,这样回路才不会变得不稳定。换句话说,它在增加活动线程数方面并不是特别快。

如果您提前知道线程非常糟糕,运行宁 许多 秒没有真正的 cpu 负载然后总是选择 LongRunning .否则这是一项调优工作,在完成时观察程序并对其进行修补以使其更优化。