如何测试调用进程是否为fork

时间:2017-02-11 14:13:04

标签: c linux fork exec posix

Linux / POSIX中是否有方法或C api来确定当前进程是否为fork?即如果是通过调用fork()创建的,而不是后续调用execve()系列?

我不控制导致这一点的代码(它在高级语言绑定中运行)。我只需要知道当前进程是在运行顶级程序,还是在其中。

我提出的最好的方法是测试该进程是否与其父进程具有相同的gid:

int is_fork = getpgid(0) == getpgid(getppid());

但是,这仅在父母已调用setpgid()时才有效,显然execve()默认情况下不会这样做。所以这会导致许多误报。

4 个答案:

答案 0 :(得分:1)

在Linux上,一个有点不精确的检查是查看进程的可执行文件(/proc/$pid/exe)是否与其父进程相同。但是,如果进程exec是自己的可执行文件,那么它将无法工作,这在某些环境中可能很常见(例如shell)。

答案 1 :(得分:0)

也许您可以使用tms_utimetms_stimetms_cutimetms_cstime(请参阅http://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html)。这些变量在子进程中设置为0

未测试

答案 2 :(得分:0)

如果您可以控制顶级可执行文件的环境,则可以使用LD_PRELOAD预加载安装pthread_atfork处理程序的共享库,该处理程序通过设置全局可见来将子项标记为分叉。然后,您的测试代码可以检查变量的值,以确定过程是否已经分叉而没有介入exec

答案 3 :(得分:-1)

/* ppid.c
cc -Wall ppid.c -o ppid
 */

#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
int pid, ppid, pgid;

pid = getpid();
ppid = getppid();
pgid = getpgid(0);

printf("[%s] Pid=%d Ppid=%d Pgid=%d\n"
        , argv[0], pid, ppid, pgid);

return 0;
}
/* testppid.c
cc -Wall testppid.c -c testppid
*/

#include <stdio.h>
#include <unistd.h>

int main(void)
{
int pid, pid2; 

pid = fork();
if (pid == -1) return 1;

if (pid) { /* parent */
        char *args[] = { "Parent", NULL};
        sleep(3);
        execve("./ppid", args, NULL);
} else { /* child */

        pid = getpid();
        setpgid(pid,pid);
        pid2 = fork();
        if (pid2 == -1) return 1;

        if (pid2) { /* child1 */
                char *args[] = { "Child1", NULL};
                sleep(2);
                execve("./ppid", args, NULL);

        } else { /* grandchild */
                char *args[] = { "Child2", NULL};
                sleep(1);
                execve("./ppid", args, NULL);
                }
        }

return 0;
}

输出:

$ ./testppid
[Child2] Pid=6220 Ppid=6219 Pgid=6219
[Child1] Pid=6219 Ppid=6218 Pgid=6219
[Parent] Pid=6218 Ppid=27410 Pgid=6218
$

这表明shell(pid = 27410)与Child1在调用Child2:{fork,setpgid,exec}之前的做法基本相同。 Child1是自己和Child2(孙子)的过程组负责人