C linux中的分叉

C linux中的分叉,c,linux,exec,fork,C,Linux,Exec,Fork,我在理解linux中的fork()时遇到了一些问题 让我困惑的是,如果父进程分叉子进程,而该子进程调用execl()和 execl()不返回,并且父进程等待子进程退出,然后系统会继续吗 吊死 提前感谢您的帮助 下面是来自mdadm的代码示例。因此在execl()之后的子进程中有exit(1)。 如果execl()没有返回,那么是否会退出(0)执行?如果没有,那么家长将无限期地等待?我就在这里吗 if (!check_env("MDADM_NO_SYSTEMCTL")) switch(fo

我在理解linux中的
fork()
时遇到了一些问题

让我困惑的是,如果父进程分叉子进程,而该子进程调用
execl()

execl()
不返回,并且父进程等待子进程退出,然后系统会继续吗

吊死

提前感谢您的帮助

下面是来自mdadm的代码示例。因此在
execl()之后的子进程中有
exit(1)
。 如果
execl()
没有返回,那么
是否会退出(0)
执行?如果没有,那么家长将无限期地等待?我就在这里吗

if (!check_env("MDADM_NO_SYSTEMCTL"))
    switch(fork()) {
    case 0:
        /* FIXME yuk. CLOSE_EXEC?? */
        skipped = 0;
        for (i = 3; skipped < 20; i++)
            if (close(i) < 0)
                skipped++;
            else
                skipped = 0;

        /* Don't want to see error messages from
         * systemctl.  If the service doesn't exist,
         * we start mdmon ourselves.
         */
        close(2);
        open("/dev/null", O_WRONLY);
        snprintf(pathbuf, sizeof(pathbuf), "mdmon@%s.service",
             devnm);
        status = execl("/usr/bin/systemctl", "systemctl",
                   "start",
                   pathbuf, NULL);
        status = execl("/bin/systemctl", "systemctl", "start",
                   pathbuf, NULL);
        exit(1);
    case -1: pr_err("cannot run mdmon. "
            "Array remains readonly\n");
        return -1;
    default: /* parent - good */
        pid = wait(&status);
        if (pid >= 0 && status == 0)
            return 0;
    }
if(!check_env(“MDADM_NO_SYSTEMCTL”))
开关(fork()){
案例0:
/*修正你的问题。结束你的执行*/
跳过=0;
对于(i=3;跳过<20;i++)
如果(关闭(i)<0)
跳过++;
其他的
跳过=0;
/*不希望看到来自的错误消息
*systemctl。如果服务不存在,
*我们自己动手。
*/
关闭(2);
打开(“/dev/null”,仅限O_wr);
snprintf(pathbuf,sizeof(pathbuf),“mdmon@%s.service”,
德夫南);
status=execl(“/usr/bin/systemctl”,“systemctl”,
“开始”,
pathbuf,NULL);
status=execl(“/bin/systemctl”、“systemctl”、“start”,
pathbuf,NULL);
出口(1);
案例1:pr_err(“无法运行mdmon。”
“数组保持只读\n”);
返回-1;
默认值:/*父级-良好*/
pid=等待(&状态);
如果(pid>=0&&status==0)
返回0;
}

如果一个进程正在等待另一个进程,而另一个进程调用exec(),那么获得exec的进程现在就是第一个进程正在等待的进程。因此,系统不会挂起,并且当exec'd进程退出时,第一个进程将继续执行。

如果一个进程正在等待另一个进程,而另一个进程调用exec(),那么获得exec'd的进程现在就是第一个进程正在等待的进程。因此,系统不会挂起,如果执行进程退出,第一个进程将继续执行。

首先,请注意,
execl
永远不会返回(除非出现错误,这意味着
execl
失败,即它“什么都没有做”——子进程仍在同一模块中执行)

如果父进程等待子进程退出,那么它显然会阻止这样做。然而,这是预期的行为,与“系统挂起”不同。系统没有挂起

编辑:
关于编辑问题中发布的代码:首先,使用
fork
创建过程的[几乎]精确副本。实际上,一个人并不关心创建一个重复的过程,但他确实想要创建一个新的过程。但是,在Unix下,新进程是分叉的,不是从头开始创建的。
然后执行两个调用
execl
。通常,第一个应该永远不会回来。相反,将加载可执行文件
systemctl
以替换子进程,子进程将从
systemctl
的入口点继续运行(这是一个非常简单的描述,但本质上是这样的)。
因此,
systemctl
将作为一个“新的”独立进程运行(实际上,它“偷走”了分叉进程!),并且它(希望)最终将退出,这将导致父进程从
等待
返回

但是,可能会出现在
/usr/bin
中找不到
systemctl
的情况(或出现其他错误)。对于这种情况,上述代码的程序员再次尝试从
/bin
加载
systemctl
。同样,如果这样做有效,
execl
将不会返回,但是
systemctl
中的代码将执行并最终退出。然后父进程将从
wait
取消阻止


最后,如果对
execl
的第二次调用也失败(即返回),作者将放弃并简单地调用
exit(1)
,这将向从
wait
唤醒的家长返回一个非零“错误”代码。首先,请注意
execl
从不返回(除非有错误,这意味着
execl
失败,即它“什么也没做”——子进程仍在同一模块中执行)

如果父进程等待子进程退出,那么它显然会阻止这样做。然而,这是预期的行为,与“系统挂起”不同。系统不会挂起

编辑:
关于编辑问题中发布的代码:首先,使用
fork
创建流程的[几乎]精确副本。实际上,人们并不关心创建副本,而是真正想要创建一个新流程。但是,在Unix下,新流程是分叉的,而不是从头创建的。
然后对
execl
进行两次调用。通常,第一次调用应该不会返回。相反,将加载可执行文件
systemctl
,以替换子进程,子进程将从
systemctl
的入口点继续运行(这是一个非常简单的描述,但本质上是这样的).
因此,
systemctl
将作为一个“新的”独立进程运行(实际上,它“偷走”了分叉进程!),并且它(希望)最终将退出,这将导致父进程从
等待
返回

但是,可能会出现在
/usr/bin
中找不到
systemctl
的情况(或出现其他错误)。对于这种情况,上述代码的程序员再次尝试从
/bin
加载
systemctl
。同样,如果这样做有效,
execl
将不会返回,但
systemctl
中的代码将执行并最终退出。父进程