在Linux中创建独立流程

时间:2015-05-12 19:46:16

标签: c++ linux process fork posix

我希望在Linux上实现类似于CreateProcess的功能。我做了很多研究,发现"Fork off and die"方法使用双叉来在init下运行子进程。也就是说,允许孩子独立于父母进行操作。

因为父母需要返回有关新创建的子进程的信息(即pid,名称等),我需要知道我是否在我的代码中遇到了竞争条件。目前,我通过管道分叉并检索第二个fork的pid,然后等待第一个fork退出。

int child = 0;
int fd[2] = { 0, 0 };

if (pipe (fd) != 0)
    return Process();

int pid = fork();
if (pid < 0)
    return Process();

if (pid == 0) // Child
{
    if (setsid() != -1)
    {
        child = fork();
        if (child == 0)
        {
            umask (0); // Reset umask
            close (0); // Close stdin
            close (1); // Close stdout
            close (2); // Close stderr

            execvp ( ... );
            _exit (0);
        }

        // Do I need waitpid (child) here?
    }

    // Write the child PID using the pipe
    write (fd[1], &child, sizeof (child));
    _exit (0);
}

else // Parent
{
    // Read the child PID using the pipe
    read (fd[0], &child, sizeof (child));

    // Remove zombie process
    waitpid (pid, nullptr, 0);

    // Child must finish exec by this point

    return Process (child);
        // Also gets name
}

问题:

  • 我是否需要第二个waitpid来等待孩子完成执行?
  • waitpid会在调用exec后返回吗?
  • 即使在waitpid之前调用了exit或exec,waitpid也会返回吗?

2 个答案:

答案 0 :(得分:0)

第二个孩子不需要waitpid()。当进程的父进程死亡时,init进程将采用该进程,因此不会出现僵尸进程。

waitpid()仅在退出时等待的孩子返回。在孩子中调用execvp()意味着服务员等待,直到执行的程序死亡,因为这是孩子死亡的时候。

waitpid()将获得流程的退出状态。这个过程实际退出的时间并不重要。

答案 1 :(得分:0)

(稍微澄清一下:你所谓的孩子,实际上是你的孙子。这个过程的孩子刚刚分手并死去。)

  
    

我是否需要第二个waitpid等待孩子完成执行?

  

你不能。它是你的孙子,你只能等待你的直接孩子。此外,由于您的孙子的父母已经去世,您的孙子现在已经被重新授予了init(因此它实际上是您的前孙子女)。

  
    

waitpid在调用exec后会返回吗?

  

Waitpid在给定的pid死亡/退出时返回,或者如果它已经是僵尸则立即返回。该孙女在孙子中被召唤。您的waitpid电话根本不关心您的直接孩子的流程(除非您使用的是仅限Linux的子级别子功能)。

  
    

即使在waitpid之前调用了exit或exec,waitpid也会返回吗?

  

Waitpid只有在等待pid(必须是你的直接孩子)已经死亡时才会返回。如果情况不是这样,它将会阻止。