为什么当我在fork()之前使用dup2()时它不起作用?

问题描述 投票:1回答:1

我想制作一个shell,我想处理多个管道。我试着理解dup2()和fork的工作原理。通常,fork()创建一个与父父完全相同的新子进程。但是当我在fork之前使用dup2时,它似乎不适用于我应该做的事情。但是当我在子进程中使用dup2()时它可以工作......我不明白,因为通常fork会创建一个调用进程的副本...

有人可以解释原因吗?

这不起作用:

int fd = open("toto.txt", O_RDONLY);
char str[10] = {0};
int test[2] = {0, 0};
char *av[] = {"/bin/ls", NULL};

pipe(test);
dup2(test[1], 1);
if (fork() == 0) {
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}

但这有效:

int fd = open("toto.txt", O_RDONLY);
char str[10] = {0};
int test[2] = {0, 0};
char *av[] = {"/bin/ls", NULL};

pipe(test);
if (fork() == 0) {
    dup2(test[1], 1);
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}
c shell fork dup2
1个回答
1
投票

原件无法正常工作,因为:

dup2(test[1], 1);
if (fork() == 0) {
    execve(av[0], av, env);
}
else {
    wait(NULL);
    read(test[0], str, 10);
    write(1, str, 10);
}

dup2标准输出重定向到管道后。此重定向适用于父级和子级。因此,该行:

    write(1, str, 10);

将其数据写回管道,而不是原始的stdout(丢失)。

通过将dup2移动到fork()之后,并且仅移动到子进程,父级的原始stdout被单独留下。在这种情况下,只有孩子的stdout被重定向。

注意:在读取管道之前调用wait将适用于示例中的小管道流量,但不适用于大流量。问题是管道的缓冲区有限。缓冲区满后,管道开始阻止写入。 wait将等待孩子完成,但孩子将在管道上等待父母读取。当流量足够大时,这可能会成为僵局。

© www.soinside.com 2019 - 2024. All rights reserved.