【问题标题】:Find PID of a Process by Name without Using popen() or system()不使用 popen() 或 system() 按名称查找进程的 PID
【发布时间】:2010-09-27 08:41:33
【问题描述】:

我有一个进程名称,我必须向该进程发送一个kill() 信号,但我需要它的 PID 来调用kill()。我只想使用:

popen("pidof process_name");

最后一件事。有没有其他方法可以找出进程的PID?我能想到的一种方法是向该进程发送一个套接字请求并询问其 PID。

对于我正在编写的简单代码而言,另一种方法有点过于复杂:执行 pidof command's source code 实际正在执行的操作(它使用函数调用 find_pid_by_name(),但它会做很多事情)。

如果没有简单的解决方案,我必须这样做:

system("pkill <process_name>");

并检查其返回码。但是 pkill 肯定会在所有 Linux 机器上可用吗?

【问题讨论】:

    标签: c unix signals kill pid


    【解决方案1】:

    您提到您使用的是 linux。这不是最干净的解决方案,但您可以检查 /proc 中的每个条目,并根据您要查找的内容检查 cmdline 中的进程名称。

    【讨论】:

    • 我认为使用 boost::regex 和 boost::filesystem 应该很简单
    • 我曾经查看过 pidof 的 strace 输出,并认为它也是这样做的。 (但可能在两者之间发生了变化)
    • procfs 读取非常便宜。出于这个特殊目的,您不必开始真正阅读,直到您达到 PID 1000,然后您有 40 - 60 个要检查。不要把它看成是阅读传统的FS,它便宜得多。
    【解决方案2】:

    使用 sysctl - Example code

    编辑 - 它在 Linux 中可用 see here

    【讨论】:

      【解决方案3】:

      Procfs 读取非常便宜,很多人认为遍历 /proc 就像遍历 / 一样,实际上根本不是这样。

      通过跳过任何低于 1000 的条目来节省一些时间,检查内核线程是没有意义的。所以,基本上……在 opendir() 之后,如果 strtoint() 认为该条目是一个 int ,并且该 int 大于或等于 1000,则只需读取 /proc/%d/stat。

      尽量避免只解决“exe”链接的冲动,因为这不会告诉您将接收信号的进程的状态。例如,如果目标处于状态“D”(磁盘睡眠),您会想知道,如果 D 状态是永久的,信号将不会立即传递,或者可能永远不会传递。

      在大多数系统上,需要检查 70 到 120 个进程,您通常会在到达终点之前找到目标路径。

      【讨论】:

      • @tinkertim:感谢您的提示,不知道在 /proc 中阅读不像阅读 FS!
      【解决方案4】:

      您提到,“我能想到的一种方法是向该进程发送套接字请求并询问其 PID。”听起来您要杀​​死的进程是您编写的程序。

      如果是这种情况,规范的做法是在程序运行时将 pid 存储在一个文件中(通常在 /var/run 下,如果您可以访问它),并在程序退出时删除该文件.这样,检测程序是否在运行就这么简单

      if kill -0 $(cat /var/run/myprog.pid 2>/dev/null) 2>/dev/null; then
          echo Running!
      else
          rm -f /var/run/myprog.pid
          echo "Not running."
      end
      

      仔细研究上述代码的所有含义可能会教您很多关于 PID 文件如何工作的知识。或者你可以要求更详细的解释。

      【讨论】:

        【解决方案5】:

        这对我来说似乎很好。

        不过,您可能希望提供进程的完整路径,以免杀死具有相似名称的进程。

        这样做的主要优点是您可以指定要发送的信号。

        system("killall -s 9 process_name");
        

        【讨论】:

          【解决方案6】:

          为什么不将 fcntl 与 F_GETOWN 一起使用?

          【讨论】:

          【解决方案7】:

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-01-21
            • 2021-05-14
            • 2012-01-22
            • 2011-12-20
            • 2011-06-16
            • 2012-03-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多