[英]A parallel process scenario realization stuck on waiting input
I am trying to realize this scenario: 我正在尝试实现这种情况:
parallel process scenario 并行流程场景
where ls -l
and cat /etc/group
processes run parallel, and tr /az/ /AZ/
takes combined input from them. 其中
ls -l
和cat /etc/group
进程并行运行,而tr /az/ /AZ/
从中获取组合的输入。 And then transfers uppercase version of them to either cat -n
and grep Z
(they also should run parallel). 然后将它们的大写版本传输到
cat -n
和grep Z
(它们也应该并行运行)。 cat -n
and grep Z
should output to stdout. cat -n
和grep Z
应该输出到stdout。
So in the stdoutput, 因此在stdoutput中,
(ls -l ; cat /etc/group) | tr /az/ /AZ/ | cat -n
(ls -l ; cat /etc/group) | tr /az/ /AZ/ | grep A
should be printed. 应该打印出来。
I've written this program to achieve my goal: 我已经编写了此程序来实现我的目标:
#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;
}
But the program stucks on read(extraPipe[0], buf, 4096);
但是程序卡在
read(extraPipe[0], buf, 4096);
line. 线。 What am I doing wrong?
我究竟做错了什么? Can you help me?
你能帮助我吗?
The two processes i == 2
are still waiting for each other. i == 2
的两个进程仍在互相等待。 I moved backward some close()
and it seems to work properly. 我向后移了一些
close()
,它似乎正常工作。 Also need a loop
for the duplicating process and an exit(0);
还需要一个用于复制过程的
loop
和一个exit(0);
rather than a break;
而不是
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.