有时每当我在Linux中编写程序并因某种错误而崩溃时,它将成为一个不间断的过程并继续运行直到我重新启动计算机(即使我退出)。我的问题是:
答案 0 :(得分:170)
不间断进程是一个恰好在系统调用(内核函数)中的过程,不能被信号中断。
要理解这意味着什么,您需要了解可中断系统调用的概念。经典的例子是read()
。这是一个系统调用,可能需要很长时间(秒),因为它可能涉及旋转硬盘驱动器或移动磁头。在大多数情况下,该过程将处于休眠状态,阻塞硬件。
当进程在系统调用中休眠时,它可以接收到unix异步信号(比如SIGTERM),然后发生以下情况:
从系统调用早期返回使用户空间代码能够立即改变其响应信号的行为。例如,在对SIGINT或SIGTERM作出反应时干净地终止。
另一方面,不允许以这种方式中断某些系统调用。如果系统由于某种原因调用了停顿,则该过程可以无限期地保持在这种不可杀死的状态。
LWN在7月份运行了一个nice article来触及这个话题。
回答原来的问题:
如何防止这种情况发生:找出导致您遇到麻烦的驱动程序,并停止使用或成为内核黑客并修复它。
如何在不重启的情况下终止不间断进程:以某种方式使系统调用终止。在不敲击电源开关的情况下,最有效的方法是拉动电源线。您也可以成为内核黑客并使驱动程序使用TASK_KILLABLE,如LWN文章中所述。
答案 1 :(得分:42)
当进程处于用户模式时,它可以随时中断(切换到内核模式)。当内核返回用户模式时,它会检查是否有任何待处理的信号(包括用于终止进程的信号,例如SIGTERM
和SIGKILL
)。这意味着只有在返回用户模式时才能终止进程。
在内核模式下无法终止进程的原因是它可能会破坏同一台机器中所有其他进程使用的内核结构(杀死线程的方式可能会破坏其他线程使用的数据结构。同样的过程)。
当内核需要做一些可能需要很长时间(等待另一个进程写入的管道或等待硬件做某事的事情)的事情时,它会通过将自己标记为休眠并调用调度程序来休眠切换到另一个进程(如果没有非休眠进程,它会切换到一个“虚拟”进程,告诉cpu减慢一点并坐在循环中 - 空闲循环)。
如果信号被发送到休眠进程,则必须先将其唤醒,然后才能返回用户空间,从而处理待处理信号。这里我们区分了两种主要的睡眠类型:
TASK_INTERRUPTIBLE
,可中断的睡眠。如果任务标记有此标志,则它正在休眠,但可以被信号唤醒。这意味着将任务标记为休眠的代码期望可能的信号,并且在唤醒之后将检查它并从系统调用返回。处理完信号后,系统调用可能会自动重启(我不会详细介绍其工作原理)。TASK_UNINTERRUPTIBLE
,不间断的睡眠。如果一个任务被标记了这个标志,那么它不会被它正在等待的任何东西唤醒,因为它不能轻易地重新启动,或者因为程序期望系统调用是原子的。这也适用于已知非常短暂的睡眠。 TASK_KILLABLE
(在与ddaa的答案相关联的LWN文章中提到)是一种新变体。
这回答了你的第一个问题。至于你的第二个问题:你无法避免不间断的睡眠,它们是正常的事情(例如,每当一个进程从磁盘读取/写入磁盘时就会发生这种情况);但是,它们应该只持续一秒钟。如果它们持续的时间更长,通常意味着硬件问题(或设备驱动程序问题,看起来与内核相同),其中设备驱动程序正在等待硬件做一些永远不会发生的事情。它也可能意味着您正在使用NFS并且NFS服务器已关闭(它正在等待服务器恢复;您还可以使用“intr”选项来避免此问题)。
最后,你无法恢复的原因与内核等到返回用户模式以传递信号或终止进程的原因相同:它可能会破坏内核的数据结构(等待可中断睡眠的代码可能会收到错误它告诉它返回用户空间,进程可以被杀死;等待不间断睡眠的代码不会出现任何错误)。
答案 2 :(得分:20)
在页面错误后,不间断进程通常会等待I / O.
考虑一下:
在这种状态下,进程/任务不能被中断,因为它无法处理任何信号;如果是的话,会发生另一个页面错误,它会回到原来的位置。
当我说“进程”时,我的意思是“任务”,它在Linux(2.6)下大致转换为“线程”,在/ proc中可能有也可能没有单独的“线程组”条目
在某些情况下,它可能会等待很长时间。一个典型的例子是可执行文件或mmap'd文件位于服务器发生故障的网络文件系统上。如果I / O最终成功,则任务将继续。如果它最终失败,任务通常会得到一个SIGBUS或其他东西。
答案 3 :(得分:0)
到第3个问题:
我认为你可以通过运行来杀死不间断的进程
sudo kill -HUP 1
。
它将重新启动init而不会结束正在运行的进程,并且在运行它之后,我的不间断进程就消失了。
答案 4 :(得分:-2)
如果你在谈论一个“僵尸”进程(在ps输出中被指定为“zombie”),那么这是一个无害的记录,在进程列表中等待有人收集它的返回代码,它可以被安全地忽略
您能否描述一下什么和“不间断的过程”适合您?它能幸免于“杀戮-9”并幸福地突然出现吗?如果是这种情况,那么它会停留在一些系统调用中,这会停留在某个驱动程序中,并且你会坚持这个过程直到重新启动(有时最好重新启动)或卸载相关驱动程序(这不太可能发生) 。您可以尝试使用“strace”来找出您的流程卡在哪里并在将来避免它。