说到.NET Threadpool我想大家都知道,只是平时比较零散,顾现在整理一下:
一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相
.NET Threadpool starvation, and how queuing makes it worse
New and Improved CLR 4 Thread Pool Engine
所以本文主要是验证和这里这几个文章
Threadpool queue
当您调用ThreadPool.QueueUserWorkItem时,就是想象一个全局队列,其中工作项(本质上是委托)在全局队列中排队,多个线程在一个队列中选择它们。先进先出顺序。
左侧的图像显示了主程序线程,因为它创建了一个工作项; 第二个图像显示代码排队3个工作项后的全局线程池队列; 第三个图像显示了来自线程池的2个线程,它们抓取了2个工作项并执行它们。如果在这些工作项的上下文中(即来自委托中的执行代码),为CLR线程池创建了更多的工作项,它们最终会出现在全局队列中(参见右图),并且生命仍在继续。
在CLR 4中,线程池引擎已对其进行了一些改进(它在CLR的每个版本中都进行了积极的调整),并且这些改进中的一部分是在使用新的System.Threading.Tasks时可以实现的一些性能提升。创建和启动一个Task(传递一个委托),相当于在ThreadPool上调用QueueUserWorkItem。通过基于任务的API使用时可视化CLR线程池的一种方法是,除了单个全局队列之外,线程池中的每个线程都有自己的本地队列
正如通常的线程池使用一样,主程序线程可以创建将在全局队列(例如Task1和Task2)上排队的任务,并且线程将通常以FIFO方式获取这些任务。事情分歧的是,在执行任务的上下文中创建的任何新任务(例如,Task2,Task23)最终在该线程池线程的本地队列上。
因此,从图片中进一步提升,让我们假设Task2还创建了另外两个任务,例如Task4和Task5。
任务按预期结束在本地队列上,但是线程选择在完成当前任务(即Task2)时