我试图了解如何在linux下使用可抢占内核实现多线程调度。特别是如何在多线程、多核环境中执行系统调用。
如果我理解正确,linux内核使用的是一对一模型,即对于每个用户级线程,都会创建一个专用的内核线程。现在我不确定我是否正确理解调度程序如何处理线程。
通过下面的例子,我想描述一下我目前的理解:
假设我们有一个由2个CPU和3个用户级线程(T1、T2、T3)组成的平台。另外,linux内核将创建3个专用的内核线程(分别是kT1、kT2、kT3)。
让我们假设在时间t0,线程T1和T2被选择在2个可用cpu上并行执行。还没有相应的内核线程在运行,因为到目前为止还没有系统调用疯掉。
在时间t1,线程t1调用系统调用。因此线程T1被挂起,CPU1被分配给内核线程kT1。
现在让我们假设在时间t2,内核线程kT1必须等待一些I/0。因此,调度程序挂起kT1并选择用户级线程T3在CPU1上执行。
在时间t3,线程T2也调用一些syscall。
T2被挂起,CPU2被分配给内核线程kT2。
在时刻t4,kT1一直等待的数据变为就绪。调度器选择(随机)抢占kT2并将CPU2分配给kT1。
在时刻t5,kT1的syscall执行返回到用户空间。也就是说,kT1变为不可运行,并且选择T1在CPU2上执行。
在时间t6,用户空间线程T3终止,CPU1被分配给kT2。
在时间t7,kT2的syscall执行返回到用户空间。
这就是运行时执行的方式吗?调度程序是否知道内核和用户空间线程之间的区别,或者它们是否被同等对待(如本例所示)?
线程优先级/好的值呢。内核线程是否从相应的用户级线程继承这些属性?
最佳答案
这是有区别的。为了避免争用情况,抢占内核线程要困难得多。所以,是的,调度器需要知道两种线程类型之间的区别。但总的来说,你所描述的情况是可能发生的。
可能是一篇关于这个主题的有用文章:
https://unix.stackexchange.com/questions/5180/what-is-the-difference-between-non-preemptive-preemptive-and-selective-preempti
关于linux - Linux调度程序在多核平台上如何处理系统调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51838679/