【发布时间】:2016-03-31 18:08:57
【问题描述】:
请考虑以下代码:
#include<stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#define READ 0
#define WRITE 1
int fd[2];
void execute(char*[], int mode);
int main()
{
char * command1[3] = {"cat", "output.txt", NULL};
char * command2[3] = {"wc", "-l", NULL};
pipe(fd); // creating pipe...
execute(command1, WRITE); // execute command1 and write output to pipe
execute(command2, READ); // execute command2 and get output from pipe
return 0;
}
//....................... DEFINATION .......................
void execute(char* command[], int mode)
{
pid_t pid;
pid = vfork();
if(pid == 0)
{
if(mode == WRITE) // writes successfully to the pipe...
{
close(1);
dup(fd[WRITE]);
close(fd[READ]);
close(fd[WRITE]);
execvp(command[0], command);
}
else if(mode == READ) // doesnot read from the pipe and goes to the wait state...
{
close(0);
dup(fd[READ]);
close(fd[WRITE]);
close(fd[READ]);
execvp(command[0], command);
}
}
else if(pid > 0)
{
wait(NULL);
}
}
我正在尝试编写一个程序,该程序使用管道将第一个进程的标准输出重定向为第二个进程的标准输入。但我面临一个问题。上面的代码执行了第一个命令“command1”并成功将数据写入管道。但是第二个命令“command2”不会从管道中读取数据,而是进入某种等待/阻塞状态。我不知道问题是什么。如果写入管道成功,为什么从管道读取不成功?
非常感谢您的帮助。提前谢谢!!!
【问题讨论】:
-
man vfork: vfork() 函数与 fork(2) 具有相同的效果,除了如果 vfork() 创建的进程修改了除pid_t 类型的变量用于存储来自 vfork() 的返回值,或从调用 vfork() 的函数返回,或在成功调用 _exit(2) 或 exec(3) 系列之一之前调用任何其他函数 为什么你现在曾经使用
vfork()? -
@EOF 高效,不复制父进程的地址空间。如果你想在 child 中执行 exec() 操作,最好使用 vfork ......无论如何我也使用了 fork 命令,它给出了相同的结果......
-
您可能认为
vfork()更“高效”,但也更难正确使用。特别是,您没有正确使用它,因此您的程序表现出未定义的行为。 -
现在,vfork 并没有比 fork 效率高多少(fork 已经优化了很多年)。 vfork 只是被认为是过时的。
-
不要使用
dup;使用dup2。dup2(fd[WRITE], STDOUT_FILENO);完成close(STDOUT_FILENO); dup(fd[WRITE]);但不依赖STDOUT_FILENO是编号最小的未使用 fd。几十年前,Unix 添加了dup2是有原因的。
标签: c operating-system