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

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

解决方法:

重要的是要理解定时器中断只是调用调度的几百个不同原因之一.只有那些运行时由计算所支配的程序(这比你想象的要少)才会花费时间.对于程序来说,一次只能运行几微秒(是的,微秒),系统调用中的“阻塞”,等待用户输入等等,这种情况更为常见.


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

就在此之前,do\_exit调用exit\_notify,它负责将SIGCHLD发送到父进程和/或从等待调用中释放它.因此,很多时候,父进程将在调度计划时准备好运行,并将被选中.

do\_exit还释放所有用户空间状态和与进程关联的大部分内核状态,释放内存,关闭文件描述符等.task\_struct本身必须存活,直到有人调用wait,我无法确切知道如何kernel决定现在可以解除分配;这段代码太复杂了.

如果进程调用_exit,则内核调用链只是sys_exit_group到do\_group\_exit到do\_exit.如果它采用致命的同步信号(例如SIGSEGV),则呼叫链会更长并且在其中具有棘手的转移.硬件陷阱由体系结构特定代码(例如x86 do_trap)通过force\_sig\_info和send\_signal发送到complete_signal,后者调整任务状态,然后告诉调度程序唤醒有问题的进程.令人讨厌的进程醒来,一个特定于体系结构的信号处理逻辑迷宫最终将它传递给get_signal,调用do\_group\_exit,调用do\_exit.致命的异步信号(例如,在shell提示符下输入kill 12345)从sys_kill开始,经过kill\_something\_info,group\_send\_sig\_info,do\_send\_sig\_info到send\_signal,之后一切都按上述步骤进行.在这两种情况下,直到complete\_signal的所有步骤都可能发生在任何进程上下文中,但是“违规进程唤醒”之后的所有内容都会发生在该进程的上下文中.

此描述中仅特定于Linux的部分是内核代码中的函数名称. Unix的任何实现都将具有内核函数,这些函数或多或少地执行Linux的do\_exit和schedule所做的操作,并且在执行\_exit,致命同步信号和致命异步信号时涉及的操作序列将是可识别的类似.

标签: linux, scheduler, ucontext

相关文章推荐

添加新评论,含*的栏目为必填