正在池化的C#线程中休眠

本文关键字:线程 休眠 | 更新日期: 2023-09-27 17:58:47

在这篇关于C#线程的网络教程中,Joseph Albahari写道:"不要睡在池线程中!"为什么不这样做?它对性能的影响有多大?(这并不是说我想这么做;我只是好奇。)

正在池化的C#线程中休眠

线程池中只有有限数量的线程;线程池被设计为高效地执行大量任务。它们依赖于每个任务的快速完成,这样线程就可以返回到池中并用于下一个任务。

因此,睡在线程池中的线程会耗尽线程池,最终可能会耗尽可用线程,无法处理分配给它的任务

线程池用于在不同的线程上快速执行相对较短的任务,而不必花费创建新线程的成本。线程池具有最大线程数,一旦达到该数,任务就会排队,直到线程可用。

因此,睡眠在线程池上的线程会占用队列,或者导致线程池耗尽。

线程是一个很重的对象
创建一个新线程需要大量资源,例如为托管堆栈分配1MB,创建托管线程对象、内核堆栈、内核线程对象、用户线程环境块。这一切都需要时间和记忆。因此,您不希望快速创建和销毁对象。此外,一旦有多个线程上下文切换,也会占用一些资源

线程池是CLR可以放置未使用线程的地方,以备应用程序需要。
线程池最初包含0个线程,一旦您从池中请求线程,池将快速创建为池定义的最小线程数。大约2分钟后,未使用的线程将被终止。但是,如果负载增加并且您需要更多的线程,线程池将缓慢地创建新线程,直到达到最大绑定。线程数不能超过最大值,一旦工作线程返回到池中,所有新请求都将排队并执行。在更糟糕的情况下,你可以得到OutOfMemoryException

如果从池中获取的线程被阻止,它:

  • 持有资源
  • 不做任何有价值的工作,而应用程序可能需要此线程来处理新请求
  • 通过引入块打破可扩展性