如何通过调度程序将每个进程固定到特定核心(Linux)

akr*_*kry 14 linux kernel scheduler

我现在正在研究Linux的调度程序.关于CPU核心亲和力,我想知道以下内容:

1)每个进程(线程)如何固定到核心?

有一个系统调用sched_setaffinity来更改执行进程的核心关联.但在内部,当生成进程(或线程)时,默认的Linux调度程序如何将进程(线程)分配给特定的核心?我修改了sched_setaffinity系统调用以转储有关正在从一个核心移动到另一个核心的任务的信息.

printk(KERN_INFO "%d %d %ld %lu %s\n", current->pid, current->tgid,
                                       current->state, current->cpus_allowed,
                                       current->comm);
Run Code Online (Sandbox Code Playgroud)

似乎没有上述信息的转储/var/log/messages.因此默认的调度程序以不同的方式将每个进程固定,但我无法弄清楚如何.

2)是否可以通过PID或其他信息获取核心ID?

这是我想在Linux内核中实现的.在task_struct,有一个成员叫cpus_allowed.但这是设置亲和力的掩码,而不是核心ID.我想检索一个数据,标识运行指定进程的核心.

谢谢,

Zel*_*luX 5

每个CPU都有自己的运行队列,即AFAIK,我们可以通过查找该进程所属的运行队列来查找该进程的当前CPU。给定task_struct *p,我们可以通过获得它的运行队列struct rq = task_rq(p),而struct rq有一个名为cpu的字段,我想这应该是答案。

我没有在实践中尝试过此功能,只是在线阅读了一些代码,并且不确定它是否可以工作。希望它能对您有所帮助。


Sun*_*lly 0

CPU 核心关联性是特定于操作系统的。操作系统知道如何执行此操作,您不必这样做。如果指定在哪个核心上运行,您可能会遇到各种问题,其中一些问题实际上可能会减慢进程速度。

在Linux内核中,与进程相关的数据结构task_struct包含cpu_allowed位掩码字段。它包含 n 个位,每个位对应机器中的 n 个处理器。具有四个物理核心的机器将有四个位。如果这些 CPU 核心支持超线程,它们将具有八位位掩码。如果为给定进程设置了给定位,则该进程可以在关联的核心上运行。因此,如果允许进程在任何内核上运行并允许根据需要跨处理器迁移,则位掩码将完全为 1。事实上,这是 Linux 下进程的默认状态。例如,

PID  2441: PRIO 0, POLICY N: SCHED_NORMAL, NICE 0, AFFINITY 0x3
Run Code Online (Sandbox Code Playgroud)

进程2441的CPU亲和力为0x3,这意味着它可以在Core0和Core1中使用。

应用程序还可以使用内核 API sched_set_affinity() 通过更改位掩码来指定/设置关联性。