0) { 等待(空); } },c,operating-system,C,Operating System" /> 0) { 等待(空); } },c,operating-system,C,Operating System" />

C中的管道和I/O重定向 请考虑以下代码: #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); } } #包括 #包括 #包括 #定义读取0 #定义写入1 int-fd[2]; 无效执行(字符*[],整数模式); int main() { char*command1[3]={“cat”,“output.txt”,NULL}; char*command2[3]={“wc”,“-l”,NULL}; 管道(fd);//正在创建管道。。。 执行(command1,WRITE);//执行command1并将输出写入管道 执行(command2,READ);//执行command2并从管道获取输出 返回0; } //....................... 定义。。。。。。。。。。。。。。。。。。。。。。。 无效执行(字符*命令[],整数模式) { pid_t pid; pid=vfork(); 如果(pid==0) { 如果(mode==WRITE)//成功写入管道。。。 { 关闭(1); dup(fd[WRITE]); 关闭(fd[READ]); 关闭(fd[WRITE]); execvp(命令[0],命令); } else if(mode==READ)//不从管道读取并进入等待状态。。。 { 关闭(0); dup(fd[READ]); 关闭(fd[WRITE]); 关闭(fd[READ]); execvp(命令[0],命令); } } 否则,如果(pid>0) { 等待(空); } }

C中的管道和I/O重定向 请考虑以下代码: #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); } } #包括 #包括 #包括 #定义读取0 #定义写入1 int-fd[2]; 无效执行(字符*[],整数模式); int main() { char*command1[3]={“cat”,“output.txt”,NULL}; char*command2[3]={“wc”,“-l”,NULL}; 管道(fd);//正在创建管道。。。 执行(command1,WRITE);//执行command1并将输出写入管道 执行(command2,READ);//执行command2并从管道获取输出 返回0; } //....................... 定义。。。。。。。。。。。。。。。。。。。。。。。 无效执行(字符*命令[],整数模式) { pid_t pid; pid=vfork(); 如果(pid==0) { 如果(mode==WRITE)//成功写入管道。。。 { 关闭(1); dup(fd[WRITE]); 关闭(fd[READ]); 关闭(fd[WRITE]); execvp(命令[0],命令); } else if(mode==READ)//不从管道读取并进入等待状态。。。 { 关闭(0); dup(fd[READ]); 关闭(fd[WRITE]); 关闭(fd[READ]); execvp(命令[0],命令); } } 否则,如果(pid>0) { 等待(空); } },c,operating-system,C,Operating System,我正在尝试编写一个程序,它使用管道将来自第一个进程的stdout重定向为第二个进程的stdin。但我面临一个问题。上面的代码执行第一个命令“command1”,并成功地将数据写入管道。但是第二个命令“command2”不会从管道中读取数据,而是进入某种等待/阻塞状态。我不知道是什么问题。如果向管道写入成功,那么为什么从管道读取不成功 我们将非常感谢您的帮助。提前感谢 因为父级没有关闭管道的写入部分,所以读卡器被阻止等待永远不会出现的数据(父级正在等待被阻止的子级) 只需添加一个对close(fd

我正在尝试编写一个程序,它使用管道将来自第一个进程的stdout重定向为第二个进程的stdin。但我面临一个问题。上面的代码执行第一个命令“command1”,并成功地将数据写入管道。但是第二个命令“command2”不会从管道中读取数据,而是进入某种等待/阻塞状态。我不知道是什么问题。如果向管道写入成功,那么为什么从管道读取不成功


我们将非常感谢您的帮助。提前感谢

因为父级没有关闭管道的写入部分,所以读卡器被阻止等待永远不会出现的数据(父级正在等待被阻止的子级)

只需添加一个对
close(fd[WRITE])的调用在调用
执行
函数之间

请务必关闭未使用的管道末端


您也可以不通过这种方式调用
wait
(您的子进程一个接一个地执行),在调用
execute
(调用wait两次)之后,将调用移动到
wait

因为父进程没有关闭管道的写入部分,所以读卡器被阻止等待永远不会出现的数据(家长正在等待被阻止的孩子)

只需在调用
execute
函数之间添加一个对
close(fd[WRITE]);
的调用

请务必关闭未使用的管道末端


您也可以不通过这种方式调用
wait
(您的子进程一个接一个地执行),在调用
execute
(调用wait两次)之后将调用移动到
wait

man vfork:vfork()函数与fork(2)具有相同的效果,只是如果vfork()创建的进程没有定义行为修改除用于存储vfork()返回值的pid类型变量以外的任何数据,或从调用vfork()的函数返回,或在成功调用_exit(2)或exec(3)函数族之前调用任何其他函数。为什么要使用
vfork()
现在?@EOF它是有效的,不复制父进程的地址空间。如果您想在子进程中执行exec()操作,最好使用vfork…无论如何,我也使用了fork命令,它给出了相同的结果…您可能认为
vfork()
更“有效”,但它也很难正确使用。特别是,您没有正确使用它,因此您的程序表现出未定义的行为。如今,vWork的效率并不比fork高多少(fork经过多年的优化)。vWork被认为是过时的。不要使用
dup
;使用
dup2
dup2(fd[WRITE],STDOUT_FILENO);
完成
close(STDOUT_FILENO);dup(fd[WRITE]);
但不依赖于
STDOUT_FILENO
是编号最小的未使用fd。Unix在几十年前出于某种原因添加了
dup2
,但如果vfork()创建的进程修改除用于存储vfork()返回值的pid类型变量以外的任何数据,或从调用vfork()的函数返回,或在成功调用_exit(2)或exec(3)之前调用任何其他函数,则该行为未定义函数族。现在为什么要使用
vfork()
呢?@EOF它是有效的,不复制父进程的地址空间。如果你想在子进程中执行exec()操作,最好使用vfork…无论如何,我也使用了fork命令,它给出了相同的结果…你可能会认为
vfork()
更有效“高效”,但更难正确使用。特别是,您没有正确使用它,因此您的程序表现出未定义的行为。如今,vWork的效率并不比fork高多少(fork多年来一直在优化).vWork被认为是过时的。不要使用
dup
;使用
dup2
dup2(fd[WRITE],STDOUT\u FILENO);
完成
close(STDOUT\u FILENO);dup(fd[WRITE]);
但不依赖
STDOUT\u FILENO
作为编号最小的未使用的fd。几十年前,出于某种原因,Unix添加了
dup2