【发布时间】:2016-07-15 11:25:32
【问题描述】:
我正在尝试实现这种情况:
其中ls -l 和cat /etc/group 进程并行运行,tr /a-z/ /A-Z/ 从它们获取组合输入。然后将它们的大写版本传输到cat -n 和grep Z(它们也应该并行运行)。 cat -n 和 grep Z 应该输出到标准输出。
所以在标准输出中,
(ls -l ; cat /etc/group) | tr /a-z/ /A-Z/ | cat -n
(ls -l ; cat /etc/group) | tr /a-z/ /A-Z/ | grep A
应该打印出来。
我编写了这个程序来实现我的目标:
#include<stdio.h>
#include<unistd.h>
#include<wait.h>
int main()
{
int dummy, i;
size_t size = 0;
int pipe1[2];
int pipe2[2];
int pipe3[2];
char* lsargs0[] = {"/bin/ls", "-l", NULL};
char* lsargs1[] = {"cat", "/etc/group", NULL};
char* lsargs2[] = {"tr", "/a-z/", "/A-Z/", NULL};
char* lsargs3[] = {"cat", "-n", NULL};
char* lsargs4[] = {"grep", "A", NULL};
char** am[] = {lsargs0, lsargs1, lsargs2, lsargs3, lsargs4};
char buf[4096];
pipe(pipe1);
pipe(pipe2);
pipe(pipe3);
for ( i = 0 ; i < 5 ; i++ )
{
pid_t pid = fork();
if ( pid == 0 )
{
if ( i == 0 || i == 1 ) // ls -l & cat
{
// 0 -> stdin, 1 -> pipe write end
close(pipe2[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe3[1]);
close(pipe1[0]);
dup2(pipe1[1], 1);
close(pipe1[1]);
execvp(am[i][0], am[i]);
}
else if ( i == 2 ) //TR AZ AZ
{
int extraPipe[2];
pipe(extraPipe);
int forkMaster = fork();
if ( forkMaster != 0 )
{
printf("TR az AZ fork parent\n");
//parent
close(pipe2[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe3[1]);
close(pipe1[1]);
dup2(pipe1[0], 0);
close(pipe1[0]);
close(extraPipe[0]);
dup2(extraPipe[1], 1);
close(extraPipe[1]);
//waitpid(forkMaster, &dummy, WNOHANG);
//wait(&dummy);
execvp(am[i][0], am[i]);
}
else
{
printf("TR az AZ child\n");
//child
read(extraPipe[0], buf, 4095);
//printf("%s\n", buf);
write(pipe2[1], buf, size);
write(pipe3[1], buf, size);
close(pipe1[1]);
close(pipe1[0]);
close(extraPipe[0]);
close(extraPipe[1]);
close(pipe2[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe3[1]);
break;
}
}
else if ( i == 3 ) // cat -n
{
close(pipe1[0]);
close(pipe1[1]);
close(pipe3[0]);
close(pipe3[1]);
close(pipe2[1]);
dup2(pipe2[0], 0);
close(pipe2[0]);
execvp(am[i][0], am[i]);
}
else if ( i == 4 ) //grep Z
{
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
close(pipe3[1]);
dup2(pipe3[0], 0);
close(pipe3[0]);
execvp(am[i][0], am[i]);
}
break;
}
//DON'T FORGET TO CLOSE PIPES ON PARENT
else if ( i == 4 )
{
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe3[1]);
}
}
for ( i = 0 ; i < 5 ; i++ )
{
wait(&dummy);
}
return 0;
}
但程序卡在read(extraPipe[0], buf, 4096); 行。我究竟做错了什么?你能帮帮我吗?
【问题讨论】:
-
small.c:97:29: error: 'n' may be uninitialized...您是否编译了您作为示例放置的代码?您需要在发布之前对其进行测试。 -
我用 gcc 编译成功了。但是对你来说,我移动了导致编译器出错的那一行,你能再试一次吗?
-
你使用的编译命令是什么?我建议至少
-Wall你会被警告你的变量没有初始化(这会导致未定义的行为)。 -
我确实使用了
-Wall标志,它现在编译时没有任何警告。你可以看看代码。 -
现在试图理解,带有 j 变量的 for 循环应该做什么?你要关闭一些文件描述符两次!
标签: c linux operating-system pipe fork