C linux中的分叉
我在理解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
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
中的代码将执行并最终退出。父进程