什么是不可中断的进程?
- 2024-10-12 10:28:00
- admin 原创
- 112
问题描述:
有时,每当我在 Linux 中编写程序时,如果程序由于某种错误而崩溃,它将成为一个不间断的进程,并继续运行,直到我重新启动计算机(即使我注销)。我的问题是:
什么原因导致进程变得不可中断?
我怎样才能阻止这种情况发生?
这可能是一个愚蠢的问题,但是有没有办法在不重新启动计算机的情况下中断它?
解决方案 1:
不可中断进程是恰好处于系统调用(内核函数)中的进程,不能被信号中断。
要理解这是什么意思,您需要了解可中断系统调用的概念。典型的例子是read()
。这是一个可能需要很长时间(几秒)的系统调用,因为它可能涉及启动硬盘或移动磁头。在这段时间的大部分时间里,该进程将处于休眠状态,阻塞硬件。
当进程在系统调用中休眠时,它可以接收 Unix 异步信号(例如,SIGTERM),然后发生以下情况:
系统调用过早退出,并设置为将 -EINTR 返回到用户空间。
信号处理程序已执行。
如果进程仍在运行,它会从系统调用中获取返回值,并且可以再次进行相同的调用。
提前从系统调用返回使用户空间代码能够立即改变其行为以响应信号。例如,响应 SIGINT 或 SIGTERM 而干净地终止。
另一方面,有些系统调用不允许以这种方式中断。如果系统调用因某种原因停止,则进程可以无限期地保持这种无法终止的状态。
LWN在 7 月份刊登了一篇涉及该主题的精彩文章。
回答最初的问题:
如何防止这种情况发生:找出哪个驱动程序给您带来了麻烦,然后停止使用,或者成为内核黑客并修复它。
如何在不重启的情况下终止不可中断进程:以某种方式使系统调用终止。通常,在不按下电源开关的情况下执行此操作的最有效方法是拔掉电源线。您还可以成为内核黑客并让驱动程序使用 TASK_KILLABLE,如 LWN 文章中所述。
解决方案 2:
当进程处于用户模式时,可以随时中断它(切换到内核模式)。当内核返回到用户模式时,它会检查是否有任何待处理的信号(包括用于终止进程的信号,例如SIGTERM
和SIGKILL
)。这意味着只有在返回到用户模式时才能终止进程。
不能在内核模式下终止进程的原因是,它可能会破坏同一台计算机中所有其他进程使用的内核结构(同样,终止线程可能会破坏同一进程中其他线程使用的数据结构)。
当内核需要做一些可能需要很长时间的事情(例如,等待另一个进程写入的管道或等待硬件执行某些操作)时,它会通过将自己标记为睡眠状态并调用调度程序切换到另一个进程来进入睡眠状态(如果没有非睡眠进程,它会切换到“虚拟”进程,该进程告诉 CPU 稍微放慢速度并处于循环中 - 空闲循环)。
如果向睡眠进程发送信号,则必须先唤醒该进程,然后该进程才能返回用户空间并处理待处理信号。以下是两种主要睡眠类型之间的区别:
TASK_INTERRUPTIBLE
,可中断睡眠。如果任务标有此标志,则表示该任务处于睡眠状态,但可以通过信号唤醒。这意味着将任务标记为睡眠状态的代码正在等待可能的信号,并且在唤醒后将检查该信号并从系统调用返回。处理信号后,系统调用可能会自动重新启动(我不会详细介绍其工作原理)。TASK_UNINTERRUPTIBLE
,不可中断的睡眠。如果任务标有此标志,则它不会期望被除它正在等待的任何东西以外的任何东西唤醒,要么是因为它无法轻易重新启动,要么是因为程序期望系统调用是原子的。这也可以用于已知非常短的睡眠。
TASK_KILLABLE
(ddaa 的回答所链接的 LWN 文章中提到)是一个新的变体。
这回答了您的第一个问题。至于您的第二个问题:您无法避免不间断睡眠,这是正常现象(例如,每次进程从磁盘读取/写入磁盘时都会发生这种情况);但是,它们应该只持续一小段时间。如果它们持续的时间更长,通常意味着硬件问题(或设备驱动程序问题,在内核看来是相同的),其中设备驱动程序正在等待硬件执行永远不会发生的事情。这也可能意味着您正在使用 NFS,并且 NFS 服务器已关闭(它正在等待服务器恢复;您也可以使用“intr”选项来避免该问题)。
最后,无法恢复的原因与内核等到返回用户模式才发出信号或终止进程的原因相同:它可能会破坏内核的数据结构(等待可中断睡眠的代码可能会收到一个错误,该错误告诉它返回用户空间,在那里进程可以被终止;等待不间断睡眠的代码不会出现任何错误)。
解决方案 3:
不可中断的进程通常在页面错误后等待 I/O。
考虑一下:
线程尝试访问不在核心中的页面(按需加载的可执行文件、已换出的匿名内存页面或按需加载的 mmap() 文件,它们大致相同)
内核正在尝试加载它
直到页面可用时,该过程才能继续。
在这种状态下,进程/任务不能被中断,因为它无法处理任何信号;如果被中断,就会发生另一个页面错误,并且它会回到原来的状态。
当我说“进程”时,我实际上指的是“任务”,在 Linux(2.6)下,它大致翻译为“线程”,它可能在 /proc 中有也可能没有单独的“线程组”条目
在某些情况下,它可能会等待很长时间。一个典型的例子是可执行文件或 mmap 文件位于服务器发生故障的网络文件系统上。如果 I/O 最终成功,任务将继续。如果最终失败,任务通常会收到 SIGBUS 或其他信号。
解决方案 4:
对于您的第三个问题:我认为您可以通过运行来终止不可中断的进程sudo kill -HUP 1
。它将重新启动 init 而不结束正在运行的进程,并且运行它之后,我的不可中断进程就消失了。
解决方案 5:
如果您正在谈论“僵尸”进程(在 ps 输出中被指定为“zombie”),那么这是进程列表中无害的记录,等待有人收集其返回代码,并且可以安全地忽略它。
您能否描述一下什么是“不可中断进程”?它是否能经受住“kill -9”并顺利运行?如果是这种情况,那么它卡在某个系统调用上,而系统调用又卡在某个驱动程序上,并且您将一直卡在这个进程上,直到重新启动(有时最好尽快重新启动)或卸载相关驱动程序(这不太可能发生)。您可以尝试使用“strace”找出您的进程卡在哪里,并在将来避免这种情况。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件