我正在努力实现这种情况:
其中ls -l
和cat /etc/group
进程并行运行,tr /a-z/ /A-Z/
从中获取组合输入。然后将它们的大写版本转移到cat -n
和grep Z
(它们也应该并行运行)。 cat -n
和grep Z
应输出到stdout。
所以在stdoutput中,
(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);
行。我究竟做错了什么?你能救我吗?
答案 0 :(得分:0)
两个进程i == 2
仍在等待彼此。我向后移动了一些close()
,它似乎正常工作。复制过程还需要loop
和exit(0);
而不是break;
。
#include <stdio.h>
#include <stdlib.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)
printf("pid %d = %ld\n", i, (long) pid);*/
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
close(pipe1[1]);
close(pipe1[0]);
close(pipe2[0]);
close(pipe3[0]);
fprintf(stderr, "Line %d\n", __LINE__);
close(extraPipe[1]);
do
{
size = read(extraPipe[0], buf, 4095);
if (size > 0)
{
write(pipe2[1], buf, size);
write(pipe3[1], buf, size);
}
} while (size > 0);
fprintf(stderr, "Line %d\n", __LINE__);
//printf("%s\n", buf);
close(extraPipe[0]);
close(pipe2[1]);
close(pipe3[1]);
exit(0);
}
}
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 A
{
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;
}