我正在阅读 Robert Love 的《Linux 内核开发》,他写道系统调用在进程上下文中执行并且能够休眠。当前指针将指向当前任务,即发出系统调用的进程。
我不明白的是,如果系统调用可以休眠,那么执行如何返回到系统调用?如果它运行在进程上下文中,它可以被唤醒并重新调度,但用户进程不能在内核空间中执行。当系统调用被调用时,内核是否会创建一个任务/进程来执行该系统调用?我知道来自用户空间的系统调用会导致陷阱切换到内核模式并执行相应的系统调用,但在阅读本文之前我假设系统调用无法休眠并重新安排,但我理解为什么它们应该是能够。
答案1
关键部分是这样的:
用户进程不能在内核空间执行
这是不正确的。当 Robert Love 写道系统调用在进程上下文中执行时,基本上意味着进程在内核模式下运行以运行系统调用。当内核处理系统调用时,它仍然运行在一个进程中,即调用进程。如果决定重新调度,则该进程将挂起,并在调度的任何其他进程中继续执行。
当挂起的进程恢复时,它会在内核模式下继续执行系统调用。
2.6 在调度方面的一大变化是,以前只能在用户模式下中断进程;现在,进程只能在用户模式下中断。使用可抢占式内核,进程也可以在内核模式下中断(除非它们禁用抢占式,这是围绕内核代码的关键部分完成的)。
答案2
用户进程不能从内核空间运行,不要让读者感到困惑。无论什么操作,无论是 read()、ioctl() 还是其他操作,都会通过 libc,以“syscall”汇编指令 (x86_64) 结束。这会导致 sw 中断,它是通往内核空间的桥梁,当处理程序完成时,它将控制权返回给用户空间。