【问题标题】:How can I detect hung processes in Linux using C? [duplicate]如何使用 C 检测 Linux 中挂起的进程? [复制]
【发布时间】:2010-11-05 06:09:19
【问题描述】:

可能重复:
Linux API to list running processes?

如何使用 C 检测 Linux 中的挂起进程?

【问题讨论】:

  • 我不确定是否有一个正式的东西叫做“挂起的过程”。进程通常是运行的、可运行的、阻塞的、挂起的……是否挂起并不是操作系统可以确定的。虽然,它可以使用启发式。
  • ps manual gşves 以下状态: D 不可中断睡眠(通常是 IO) R 正在运行或可运行(在运行队列上) S 可中断睡眠(等待事件完成) T 已停止,由作业控制信号或因为它正在被跟踪。 W 分页(自 2.6.xx 内核起无效) X 死机(永远不会被看到) Z 已失效(“僵尸”)进程,已终止但未被其父进程收割。
  • @Rich B ... 将其列为 dup ... 问题略有变化,变得更窄
  • 是的问题是完全改变,但我已经认识到,这几乎是不可能的通用方法。
  • 所谓的“完全重复”并没有解决确定进程是否“挂起”的问题。诚然,许多答案似乎假设这是同一个问题。这是他们的错,而不是问题的。

标签: c linux


【解决方案1】:

在 linux 下,执行此操作的方法是检查 /proc/[PID]/* 的内容,一个好的一站式位置是 /proc/*/status。它的前两行是:

名称:[程序名称] 状态:R(运行)

当然,检测挂起的进程是一个完全独立的问题。

/proc//stat 是与 /proc//status 相同信息的更机器可读的格式,实际上是 ps(1) 命令读取以生成其输出。

【讨论】:

    【解决方案2】:

    看到问题变了:

    http://procps.sourceforge.net/

    是ps等进程工具的来源。他们确实使用 proc(表明它可能是读取进程信息的传统和最佳方式)。他们的源代码可读性很强。文件

    /procps-3.2.8/proc/readproc.c
    

    您还可以将您的程序链接到 libproc,它可以在您的存储库中使用(或者我会说已经安装),但是您需要标题的“-dev”变体以及什么 -不是。使用此 API,您可以读取进程信息和状态。

    你可以通过 libproc 使用 psState() 函数来检查类似的东西

    #define PS_RUN          1       /* process is running */
    #define PS_STOP         2       /* process is stopped */
    #define PS_LOST         3       /* process is lost to control (EAGAIN) */
    #define PS_UNDEAD       4       /* process is terminated (zombie) */
    #define PS_DEAD         5       /* process is terminated (core file) */
    #define PS_IDLE         6       /* process has not been run */
    

    回应评论 IIRC,除非您的程序在 CPU 上,并且您可以从内核中用信号刺激它……您无法真正说出它的响应速度。即使这样,在陷阱之后也会调用一个信号处理程序,该处理程序可能在该状态下运行良好。

    最好的办法是在另一个内核上安排另一个进程,该进程可以在进程运行时以某种方式戳该进程(或处于循环中,或无响应)。但我在这里可能是错的,而且会很棘手。

    祝你好运

    【讨论】:

    • 谢谢 Aiden,但是如果进程没有响应,我该如何找到。例如,进程空闲的时间 + 其状态 + cpu ram stats 并在它们上构建启发式方法很有用。如果是,那可能是什么启发式方法。
    • 除非进程可以在 CPU 上被内核(或信号)触发,否则您无法判断它是否无响应 IIRC
    【解决方案3】:

    监视和/或终止进程只是系统调用的问题。我认为您问题中最棘手的部分确实是可靠地确定进程“挂起”,而不是仅仅非常忙(或等待临时条件)。

    在一般情况下,我认为这会相当困难。甚至当 Windows 认为程序可能“挂起”时,它也会要求用户做出决定(在我的系统上,这通常也是错误的)。

    但是,如果您有一个喜欢以特定方式挂起的特定程序,我认为您应该能够可靠地检测到这一点。

    【讨论】:

      【解决方案4】:

      您可以使用 strace() 使用的任何机制来确定进程正在进行的系统调用。然后,您可以确定您最终会因 pthread_mutex 死锁或其他任何事情而执行哪些系统调用......然后您可以使用启发式方法并确定一个进程是否在锁定系统调用上挂起超过 30 秒,它陷入僵局。

      【讨论】:

        【解决方案5】:

        您可以在进程 pid 上运行“strace -p”来确定它正在执行的(如果有的话)系统调用。如果一个进程没有进行任何系统调用但正在使用 CPU 时间,那么它要么被挂起,要么正在用户空间内的紧密计算循环中运行。您确实需要知道单个程序的预期行为才能确定。如果它没有进行系统调用但没有使用 CPU,它也可能只是空闲或死锁。

        做到这一点的唯一防弹方法是修改被监控的程序,以便每隔一段时间向“看门狗”进程发送“ping”,或者在请求时响应 ping 请求,例如套接字连接你可以在哪里问它“你还活着吗?”并返回“是”。该程序的编码方式可以是,如果它在某处杂草丛生并且没有正确执行,则不太可能执行 ping。我很确定这就是 Windows 知道进程挂起的方式,因为每个 Windows 程序都有某种事件队列,它在其中处理来自操作系统的一组已知 API。

        不一定是一种编程方式,但判断程序是否“挂起”的一种方法是使用 gdb 闯入它并拉回跟踪,看看它是否卡在某个地方。

        【讨论】:

        • 如果我有一个特定的程序来确定它是否挂起,我会尝试改变它的状态或发出这个过程的信号,即使你可以尝试分叉。如果它对以上任何一个都没有反应。它可能已经死了。
        猜你喜欢
        • 2012-03-07
        • 2015-12-15
        • 1970-01-01
        • 2020-10-02
        • 1970-01-01
        • 2012-09-04
        • 1970-01-01
        • 2012-06-11
        • 1970-01-01
        相关资源
        最近更新 更多