为了账号安全,请及时绑定邮箱和手机立即绑定

什么是不间断的过程?

什么是不间断的过程?

凤凰求蛊 2020-02-04 16:09:36
有时,每当我在Linux上编写程序并由于某种错误而崩溃时,它将变成一个不间断的进程,并永远运行直到我重新启动计算机(即使注销)。我的问题是:是什么导致流程变得不间断?如何阻止这种情况发生?这可能是一个愚蠢的问题,但是有什么方法可以在不重新启动计算机的情况下中断它?
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

不间断进程是恰好在系统调用(内核函数)中的进程,无法被信号打断。

要了解这意味着什么,您需要了解可中断系统调用的概念。典型的例子是read()。这是一个系统调用,可能需要很长时间(几秒钟),因为它可能涉及旋转硬盘驱动器或移动磁头。在这段时间的大部分时间内,进程将处于睡眠状态,从而阻塞硬件。

当进程在系统调用中处于睡眠状态时,它可以接收Unix异步信号(例如SIGTERM),然后发生以下情况:

  • 系统调用过早退出,并设置为将-EINTR返回给用户空间。

  • 信号处理程序被执行。

  • 如果该进程仍在运行,它将从系统调用中获取返回值,并且可以再次进行相同的调用。

从系统调用中尽早返回使用户空间代码可以响应信号立即更改其行为。例如,对SIGINT或SIGTERM的反应干净地终止。

另一方面,不允许以这种方式中断某些系统调用。如果系统由于某种原因而导致停顿,则该进程可能会无限期保持这种不可杀灭的状态。

LWN 在7月发表了一篇不错的文章,触及了这个话题。

要回答原始问题:

  • 如何防止这种情况的发生:找出造成您麻烦的驱动程序,然后停止使用或成为内核黑客并对其进行修复。

  • 如何在不重新启动的情况下杀死不间断的进程:以某种方式使系统调用终止。通常,最有效的方法是不拉电源线就拉电源线。您还可以成为内核黑客,并使驱动程序使用TASK_KILLABLE,如LWN文章中所述。


查看完整回答
反对 回复 2020-02-04
?
开满天机

TA贡献1786条经验 获得超12个赞

当进程处于用户模式时,可以随时中断它(切换到内核模式)。当内核返回用户模式时,它会检查是否有任何待处理的信号(包括用于杀死进程的信号,例如SIGTERMSIGKILL)。这意味着只能在返回用户模式后才能杀死进程。

无法在内核模式下杀死进程的原因是,它可能破坏同一台机器上所有其他进程使用的内核结构(杀死线程的潜在方式可能破坏同一进程中其他线程使用的数据结构) 。

当内核需要执行可能需要很长时间的操作(例如,等待另一个进程编写的管道或等待硬件执行某些操作)时,它会通过将自身标记为睡眠并调用调度程序以切换到另一个而进入睡眠状态进程(如果没有非睡眠进程,它将切换到“虚拟”进程,该进程告诉CPU放慢速度并处于一个循环-空闲循环)。

如果将信号发送到睡眠过程,则必须先唤醒它,然后才能返回用户空间,从而处理未决的信号。这里我们有两种主要的睡眠类型之间的区别:

  • TASK_INTERRUPTIBLE,可中断的睡眠。如果任务标记有此标志,则表明该任务正在休眠,但可以通过信号唤醒。这意味着将任务标记为休眠的代码正在等待可能的信号,并且在唤醒后将对其进行检查并从系统调用中返回。处理完信号后,系统调用可能会自动重新启动(我不会详细说明其工作原理)。

  • TASK_UNINTERRUPTIBLE,不间断的睡眠。如果一个任务标有该标志,则它不会被等待中的任何事物唤醒,要么是因为它不容易重新启动,要么是因为程序期望系统调用是原子的。这也可用于已知非常短的睡眠。

TASK_KILLABLE (在ddaa的答案链接到的LWN文章中提到)是一个新变体。

这回答了您的第一个问题。关于第二个问题:您无法避免不间断的睡眠,这是正常现象(例如,每次进程从磁盘读/写磁盘时都会发生);但是,它们只能持续一秒钟的时间。如果它们持续更长的时间,通常意味着出现硬件问题(或设备驱动程序问题,在内核看来也是如此),其中设备驱动程序正在等待硬件执行永远不会发生的事情。这也可能意味着您正在使用NFS,并且NFS服务器已关闭(正在等待服务器恢复;也可以使用“ intr”选项来避免该问题)。

最后,您无法恢复的原因与内核等待直到返回用户模式以传递信号或终止进程的原因相同:它可能破坏内核的数据结构(等待可中断睡眠的代码可能会收到错误消息,告诉它返回到可以杀死进程的用户空间;等待不间断睡眠的代码不会出现任何错误)。


查看完整回答
反对 回复 2020-02-04
?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

不间断的进程通常在页面错误后等待I / O。

考虑一下:

  • 线程尝试访问不在核心中的页面(要么是按需加载的可执行文件,已换出的匿名内存页面,要么是按需加载的mmap()文件),一样)

  • 现在,内核正在(尝试)将其加载到

  • 在页面可用之前,该过程无法继续。

进程/任务在这种状态下不能被中断,因为它不能处理任何信号。如果确实如此,则会发生另一个页面错误,并且该错误将返回到原来的位置。

当我说“进程”时,我的意思是“任务”,在Linux(2.6)下,它大致翻译为“线程”,在/ proc中可能有也可能没有单独的“线程组”条目

在某些情况下,它可能等待很长时间。一个典型的例子是可执行文件或mmap文件位于服务器发生故障的网络文件系统上。如果I / O最终成功,则任务将继续。如果最终失败,则该任务通常会获得SIGBUS之类的东西。


查看完整回答
反对 回复 2020-02-04
  • 3 回答
  • 0 关注
  • 761 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信