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

时间:2016-09-23 17:17:26

标签: linux scheduler ucontext

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

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

1 个答案:

答案 0 :(得分:4)

了解计时器中断只是为什么schedule可能被调用的几百个不同原因中的一个,这一点非常重要。只有那些运行时由计算占主导地位的程序才会耗尽它们的时间片,而这些程序比你想象的要少。对于程序来说,只运行几微秒(是的,微秒),在一段时间内,在阻塞"之间运行的情况更为常见。在系统调用中,等待用户输入或其他任何内容。

当一个进程以任何方式退出时,最终会在该进程的(内核)上下文中调用do_exitdo_exitschedule作为最后一次操作,schedule 永远不会返回该上下文。请注意,在do_exit的最后,有schedule的来电,紧接着是BUG();和无限循环。

在此之前,do_exit调用exit_notify,负责将SIGCHLD发送到父进程和/或通过调用wait将其释放。因此,很多时候,父进程将在schedule被调用时准备好运行,并将被选中。

do_exit还释放所有用户空间状态和与进程关联的大部分内核状态,释放内存,关闭文件描述符等。task_struct本身必须存在,直到有人调用{ {1}},我无法确切知道内核如何确定它现在可以解除分配;这段代码太复杂了。

如果进程调用_exit,则内核调用链只是sys_exit_groupwaitdo_group_exit。如果它采用致命的同步信号(例如do_exit),则呼叫链会更长并且在其中具有棘手的转移。硬件陷阱由特定于体系结构的代码(例如x86 do_trap)通过SIGSEGVforce_sig_infocomplete_signal进行调整,调整任务状态然后告知调度程序唤醒违规过程。令人讨厌的进程醒来,特定于体系结构的信号处理逻辑迷宫最终将其传递给get_signal,调用send_signal,调用do_group_exit。致命异步信号(例如,在shell提示符下输入do_exit)从sys_kill开始,然后通过kill 12345kill_something_info,{{1} } group_send_sig_info,然后一切按上述步骤进行。在这两种情况下,do_send_sig_info之前的所有步骤都可能发生在任何进程上下文中,但是在"违规进程唤醒之后的所有内容都会被唤醒。发生在该过程的背景下。

本说明中仅特定于Linux的部分是内核代码中的函数名称。 Unix的任何实现都将具有内核函数,这些函数或多或少地执行Linux send_signalcomplete_signal所做的事情,以及涉及部署do_exit致命同步信号的操作序列,和致命的异步信号将是可识别的相似。