12

我试图了解 linux 系统调用 sched_setaffinity() 的工作原理。这是我的问题here的后续内容。

我有这个指南,它解释了如何使用系统调用并且有一个非常简洁(工作!)的例子。

所以我下载了 Linux 2.6.27.19内核源代码

我对包含该系统调用的行进行了“grep”,得到了 91 个结果。没有希望。

最终,我试图了解内核如何为特定内核(或处理器)设置指令指针。

我熟悉单核单线程程序的工作原理。有人可能会发出“jmp foo”指令,这基本上将 IP 设置为“foo”标签的内存地址。但是当一个有多个内核时,必须说“在内存地址 foo 处获取下一条指令,并将指令指针设置为2 号内核开始执行”。

在汇编代码中,我们在哪里指定执行该操作的内核?

回到内核代码:这里重要的是什么?文件 'kernel/sched.c' 有一个名为 sched_setaffinity() 的函数,但返回类型“long” - 这与它的手册页不一致。那么这里重要的是什么?这些模块中的哪些显示了发出的汇编指令?什么模块正在读取“task_struct”,查看“cpus_allowed”成员,然后将其转换为指令?(我还翻阅了 glibc 源代码——但我认为它只是调用内核代码来完成这项任务。)

4

4 回答 4

9

sched_setaffinity()只需告诉调度程序允许在哪些 CPU 上运行进程/线程,然后调用重新调度。

调度程序实际上在每个 CPU 上运行,因此它有机会决定接下来在该特定 CPU 上执行什么任务。

如果您对如何在其他 CPU 上实际调用某些代码感兴趣,我建议您查看smp_call_function_single(). 如果我们想在另一个 CPU 上调用某些东西,它会调用generic_exec_single(). 后者只是简单地将函数添加到目标 CPU 的调用队列,并通过一些IPI内容强制重新调度(如果队列为空)。

底线是:该_jmp_指令没有实际的 SMP 变体。相反,在其他 CPU 上运行的代码会相互协作以完成任务。

于 2009-04-20T00:22:51.393 回答
4

我认为您不理解的是内核正在所有CPU 内核上运行。在每次定时器中断(每秒约 1000 次)时,调度程序在每个 CPU 上运行并选择要运行的进程。没有一个 CPU 会以某种方式告诉其他 CPU 开始运行一个进程。sched_setaffinity()只需在进程上设置标志即可工作。调度程序读取这些标志,如果设置为不运行,则不会在其 CPU 上运行该进程。

于 2009-04-20T00:40:15.907 回答
1

在汇编代码中,我们在哪里指定执行该操作的内核?

这里不涉及组装。每个任务(线程)一次被分配给一个 CPU(或您的术语中的核心)。要停止在给定 CPU 上运行并在另一个 CPU 上恢复,任务必须“迁移”(也是this)。当任务从一个 CPU 迁移到另一个 CPU 时,调度程序会在 允许的 CPU 中选择更空闲的 CPU sched_setaffinity()

没有发布任何神奇的组装指令。内核对硬件有一个更底层的视图,每个 CPU 都是一个单独的对象,与用户空间进程的外观非常不同(在用户空间,CPU 几乎是不可见的)。

于 2009-04-20T00:29:16.123 回答
-1

看看这个:B 操作系统编程指南

于 2009-12-03T15:24:26.060 回答