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



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

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

重要的是要了解计时器中断只是schedule可能被调用的数百个不同原因之一。 只有运行时由计算主导的程序(这比您想象的要少见(才会耗尽其时间片。 程序一次只运行几微秒(是的,微秒(的情况更为常见,在系统调用中的"阻塞"、等待用户输入或其他之间。

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

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

do_exit 还会释放所有用户空间状态以及与进程关联的大部分内核状态,释放内存,关闭文件描述符等。 task_struct本身必须存活到有人调用wait,我无法确切地弄清楚内核如何决定现在可以解除分配它;此代码太复杂了。

如果进程调用_exit,内核调用链只是sys_exit_groupdo_group_exit do_exit。 如果它需要致命的同步信号(例如 SIGSEGV(,调用链要长得多,并且有一个棘手的转移。 硬件陷阱由特定于架构的代码(例如x86 do_trap(通过force_sig_infosend_signal complete_signal来执行,后者调整任务状态,然后告诉调度程序唤醒有问题的进程。 有问题的进程被唤醒,一个迷宫般的特定于架构的信号处理逻辑最终将其传递给get_signal,调用do_group_exitdo_exit。 致命的异步信号(例如,在shell提示符下键入kill 12345(从sys_kill开始,经过kill_something_infogroup_send_sig_infodo_send_sig_infosend_signal,之后一切都像上面一样进行。 在这两种情况下,complete_signal之前的所有步骤都可能发生在任何进程上下文中,但"违规进程唤醒"之后的所有步骤都发生在该进程的上下文中。

此描述中唯一特定于 Linux 的部分是内核代码中的函数名称。 Unix的任何实现都将具有内核函数,这些函数或多或少地执行Linux的do_exitschedule所做的事情,并且涉及字段_exit,致命同步信号和致命异步信号的操作序列将可识别地相似。

相关内容

  • 没有找到相关文章

最新更新