为什么当我在 fork() 之前使用 dup2() 它不起作用?
Why when i use dup2() before fork() it doesn't work?
我想制作一个 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);
}
原版无法正常工作,因为:
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
标准输出被重定向到管道之后。此重定向适用于 parent 和 child。因此,行:
write(1, str, 10);
将其数据写回管道,而不是原始标准输出(已丢失)。
通过将 dup2
移动到 fork()
之后,并且仅移动到 child 进程,parent 的原始标准输出将保持不变。在那种情况下,只有 child 的标准输出被重定向。
注意:在读取管道之前调用 wait
将适用于示例中的小管道流量,但不适用于大流量。问题是管道的缓冲区有限。一旦缓冲区已满,管道就会开始阻塞写入。 wait
将等待 child 完成,但 child 将在管道上等待 parent 读取。当流量足够大时,这可能会成为死锁。
我想制作一个 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);
}
原版无法正常工作,因为:
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
标准输出被重定向到管道之后。此重定向适用于 parent 和 child。因此,行:
write(1, str, 10);
将其数据写回管道,而不是原始标准输出(已丢失)。
通过将 dup2
移动到 fork()
之后,并且仅移动到 child 进程,parent 的原始标准输出将保持不变。在那种情况下,只有 child 的标准输出被重定向。
注意:在读取管道之前调用 wait
将适用于示例中的小管道流量,但不适用于大流量。问题是管道的缓冲区有限。一旦缓冲区已满,管道就会开始阻塞写入。 wait
将等待 child 完成,但 child 将在管道上等待 parent 读取。当流量足够大时,这可能会成为死锁。