Linux 上下文切换内部:当进程在定时器中断之前退出时会发生什么?

Linux context switch internals: What happens when process exits before timer interrupt?

当进程在定时器中断之前退出时,linux内核如何进行上下文切换?

我知道如果进程是 运行ning 并且定时器中断发生然后 schedule 函数被自动调用如果标志被设置,调度函数然后选择下一个进程到 运行 .基本上在这种情况下,调度函数 运行s 在当前进程的上下文中,但是当进程甚至在定时器中断之前退出时会发生什么?在这种情况下谁调用了 schedule 函数?它在什么情况下 运行?

重要的是要了解定时器中断只是 schedule 可能被调用的数百个不同原因之一。只有 运行 时间主要由计算支配的程序(这种情况比您想象的要少)才会用完它们的时间片。对于程序来说,更常见的是 运行 一次只有几微秒——是的,几微秒——在系统调用中 "blocking" 之间,等待用户输入或其他什么。

当进程以任何方式退出时,最终调用 do_exit always happens, in the (kernel) context of that process. do_exit calls schedule 作为其最后一个操作,并且 schedule 永远不会 returns 到该上下文 .请注意,在 do_exit 的最后如何调用 schedule,紧接着是 BUG(); 和无限循环。

就在这之前,do_exit 调用 exit_notify,它负责将 SIGCHLD 发送到父进程 and/or 从对 [=21 的调用中释放它=].所以,很多时候,父进程将准备好-运行 当 schedule 被调用时,将被选中。

do_exit 还释放所有用户-space 状态和大部分与进程关联的内核状态,释放内存,关闭文件描述符等。task_struct 本身必须在有人调用 wait 之前存活下来,我无法弄清楚内核是如何决定它现在可以被释放的;这个代码太复杂了。

如果进程调用_exit, the kernel call chain is simply sys_exit_group to do_group_exit to do_exit. If it took a fatal synchronous signal (e.g. SIGSEGV), the call chain is a lot longer and has a tricky diversion in it. The hardware trap is fielded by architecture-specific code (e.g. x86 do_trap) through force_sig_info and send_signal to complete_signal, which adjusts the task state and then tells the scheduler to wake up the offending process. The offending process wakes up, and a maze of architecture-specific signal handling logic eventually delivers it to get_signal, which calls do_group_exit, which calls do_exit. Fatal asynchronous signals (e.g. from typing kill 12345 at a shell prompt) start at sys_kill,经过kill_something_infogroup_send_sig_infodo_send_sig_infosend_signal,之后一切如上。在这两种情况下,complete_signal 之前的所有步骤都可能发生在 任何 进程上下文中,但 "The offending process wakes up" 之后的所有步骤都发生在该进程的上下文中。

此描述中唯一 Linux 特定的部分是内核代码中的函数名称。 Unix 的任何实现都将具有或多或少做 Linux 的 do_exitschedule 所做的内核函数,以及字段 _exit 中涉及的操作序列,致命同步信号和致命异步信号将非常相似。