【发布时间】:2011-12-05 05:58:33
【问题描述】:
当您在进程 X 中调用诸如fork 之类的系统调用时,就说内核正在进程上下文中执行。那么,fork 可以说是在进程 X 中运行的吧?
但是如果schedule() 在同一个进程中被调用(并且它不是系统调用),你会说它作为X 的一部分运行吗?或者它是否在交换进程中运行?或者考虑到内核的单片性,这听起来很荒谬?
【问题讨论】:
当您在进程 X 中调用诸如fork 之类的系统调用时,就说内核正在进程上下文中执行。那么,fork 可以说是在进程 X 中运行的吧?
但是如果schedule() 在同一个进程中被调用(并且它不是系统调用),你会说它作为X 的一部分运行吗?或者它是否在交换进程中运行?或者考虑到内核的单片性,这听起来很荒谬?
【问题讨论】:
schedule() 始终在进程上下文中运行。它的特殊之处在于它可以改变当前的进程上下文——但它总是有一个进程上下文。在调用context_switch() 之前,它在要换出的进程的上下文中运行,在它在换入的进程中运行之后。
Linux 内核没有专门的“交换器”任务(有一个空闲任务,它始终可以运行,以防没有其他条件可以运行)。
【讨论】:
这真的取决于schedule() 调用的来源; schedule() 既可以从进程上下文调用,也可以从工作队列调用。工作队列是内核调度的线程:
# ps auxw | grep worker
root 1378 0.0 0.0 0 0 ? S 20:45 0:00 [kworker/1:0]
root 1382 0.0 0.0 0 0 ? S 20:45 0:00 [kworker/2:0]
root 1384 0.0 0.0 0 0 ? S 20:45 0:00 [kworker/3:1]
...
[..] 表示进程不在用户空间中执行。
worker_thread() 函数在处理一个工作项之后但在重新开始之前调用schedule()。
schedule() 也可以由驱动程序或信号处理代码、文件系统内部或无数其他选项代表进程调用。
【讨论】:
schedule() 被工作队列调用,它也是在进程上下文中调用的——在这种情况下,是kworker 进程的上下文。
kworker 进程没有任何用户空间内存映射,我觉得值得指出的是schedule() 在执行内核发起的代码时可能会被调用——不代表任何可能执行系统调用的进程。
调度程序负责所有进程,因此不会在一个进程中运行。
当然,例如,当一个进程由于时钟中断而被调度,某个进程正在运行(稍后,另一个进程被调度)。
您不能将所有内核都视为正在运行的进程(只有系统调用是)。
【讨论】:
Q:那么,fork 可以说是在进程 X 中运行的,对吧?
A:是的,当然。进程请求“fork”的系统调用发生在用户空间中。使系统调用从用户空间转移到内核空间的行为。系统调用的实现可能涉及许多单独的步骤。有些可能发生在用户空间;其他步骤发生在内核空间中。
问:...考虑到内核的整体性?
答:“用户空间”与“内核空间”的问题与内核是否恰好是“单片机”、“微内核”或其他完全无关。
【讨论】: