【问题标题】:How to get the PID for a background process in C code如何在 C 代码中获取后台进程的 PID
【发布时间】:2011-11-29 06:47:50
【问题描述】:

我正在使用 C 程序中的系统调用执行 linux 命令。代码 sn-p -

cmd = "sudo conntrack -E -p udp -e NEW | logger -t log-conntrack -p daemon.notice &";

system(cmd);

此命令启动 3 个进程,现在我不知何故想要“conntrack”进程的进程 ID(下例中的 PID - 31951)。

根 31949 0.0 0.4 2356 1060 pts/2 S 17:39 0:00 sudo conntrack -E -p udp -e NEW -o id 根 31950 0.0 0.1 1716 504 pts/2 S 17:39 0:00 logger -t log-conntrack -p daemon.notice 根 31951 0.0 0.2 1852 544 pts/2 S 17:39 0:00 conntrack -E -p udp -e NEW -o id

请帮忙。 谢谢

【问题讨论】:

  • system 不会后台处理进程,它会等待命令返回,您是在单独的线程中运行它还是在 fork() 之后运行它?
  • 上面提到的cmd后面有“&”,在后台运行。

标签: c


【解决方案1】:

打印其进程 ID、父进程 ID 和组 ID 的程序

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

int main() 
{
        pid_t pid, ppid;
    gid_t gid;

    /* get the process id */
    if ((pid = getpid()) < 0) {
      perror("
unable to get pid");
    } else {
      printf("
The process id is %d", pid);
    }

    /* get the parent process id */
    if ((ppid = getppid()) < 0) {
      perror("
unable to get the ppid");
    } else {
      printf("
The parent process id is %d", ppid);
    }

    /* get the group process id */
    if ((gid = getgid()) < 0) {
      perror("
unable to get the group id
");
    } else {
      printf("
The group id is %d
", gid);
    }

    return(0);
}  

【讨论】:

  • getpid() 和 getppid() 不适用于后台进程。无论如何,谢谢。
【解决方案2】:

没有简单的方法可以获取系统命令为你运行的shell运行的sudo进程(conntrack进程)的子进程的PID。

您必须摸索ps 或其等价物的输出。

如果您fork() 一个子进程,父进程会被明确告知子进程的 PID。但是,没有简单的方法可以找到system() 启动的子进程的PID。进程也没有任何标准的方式来了解它的孙子进程。在您的情况下,您有一个由system() 运行的shell,它又在一个孩子中运行logger,并在退出前一秒钟运行sudo;而sudo 又运行conntrack(而且,sudo 似乎等待conntrack 完成,而不是简单地用conntrack 替换自己)。

【讨论】:

  • 是的,我是这么认为的。有没有其他方法可以在C中执行上述命令,获取bkgnd进程的pid?
  • 您可以毫不费力地执行 shell 的操作来运行 loggersudo - 因此您可以跟踪其中一个或两个进程(没有 system() 强加给您的中间 shell )。但是,您仍然坚持使用sudo 启动自己的孩子conntrack,而且我不知道获取孩子PID 的简单方法——除非sudo 有鲜为人知的选项来完成这项工作(我在 sudo v.1.7.4 中看不到任何有希望的东西)。
  • 不使用system(),我可以做系统会做的事情,即fork()一个进程,让子exec()命令然后等待子进程的pid?
  • 是的 - 虽然您不能直接等待 conntrack 进程,但您可以在 conntrack 进程完成后等待 sudo 进程完成。 sudo 会将conntrack 的退出状态转发回您的程序,不过 - 在限制范围内。主要限制是,如果您的程序死于信号(并且可能产生核心转储),那么sudo 无法完美地传递该信息;但是,它可以(并且将)告诉命令失败。
  • 非常感谢您提供的信息,而且由于两个命令之间有管道,我也需要创建管道。我找到了您的帖子,内容如下 -
【解决方案3】:
char cmd[] = "(sudo sh -c 'conntrack -E -p udp -e NEW& echo $! >&2' |"
             " logger -t log-conntrack -p daemon.notice&) 2>&1";
int pid = 0;    // let's assume pid_t fits in an int
FILE *stream = popen(cmd, "r");
if (stream) fscanf(stream, "%d", &pid), pclose(stream);

【讨论】:

    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 2017-01-23
    • 2010-12-06
    • 2013-12-30
    相关资源
    最近更新 更多