【发布时间】:2021-08-08 15:56:18
【问题描述】:
我的问题是基于这篇文章Internals of Windows Thread
我们可以看到,对于系统中的每个线程,操作系统都会创建一个线程内核对象。操作系统使用这些线程内核对象来管理和执行整个系统的线程
每隔 20 毫秒左右,操作系统线程调度程序会查看当前处于就绪队列(双向链表)中的所有线程内核对象。线程调度程序选择线程内核对象之一,并使用最后保存在线程上下文中的值加载 CPU 的寄存器。
而CLR的线程池架构是
每个工作线程都有自己的本地队列,当一个工作线程调度一个Task时,该Task会被添加到调用该线程的本地队列中。
在此背景下,假设 .NET ThreadPool 有一些工作线程,如上图所示。假设工作线程 1 有一些工作项目在本地队列 1 中排队。工作线程 1 执行的当前任务阻塞了几秒钟(等待信号到达等,或者它正在执行一个长时间运行的任务)。
我的问题是,
A.can Worker Thread 1 暂时停止执行这个阻塞任务并切换到执行本地队列中的另一个任务,等新任务完成后再回来执行长时间运行的任务.如果是这种情况,如何保存长时间运行的任务的上下文状态?例如,我们需要将寄存器的值存储到线程内核对象 1 中,但是当 Worker Thread 1 开始执行另一个任务时,原来的任务的保存在线程内核对象 1 中的状态会丢失
或
B.Worker Thread 1 必须先完成这个长时间运行的任务,然后才能执行其本地队列中的其他任务。但这是低效的,因为 Worker Thread 1 浪费了它本可以用来执行其他任务的几秒钟。
【问题讨论】:
-
使用异步/等待。