我在实验室工作。 父进程将创建两个子进程A和B. Son A将通过pipe发送一些字符串到子B.son B将反转字符串从字母A得到的字符串案例,并将反向字符串发送给儿子A.收到反向字符串后,儿子A将其打印到屏幕
这是代码。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
void process_A(int input_pipe[], int output_pipe[])
{
int c;
char ch;
int rc;
close(input_pipe[1]);
close(output_pipe[0]);
while ((c = getchar()) > 0) {
ch = (char)c;
rc = write(output_pipe[1], &ch, 1);
if (rc == -1) {
perror("A_TO_B: write");
close(input_pipe[0]);
close(output_pipe[1]);
exit(1);
}
rc = read(input_pipe[0], &ch, 1);
c = (int)ch;
if (rc <= 0) {
perror("A_TO_B: read");
close(input_pipe[0]);
close(output_pipe[1]);
exit(1);
}
putchar(c);
}
close(input_pipe[0]);
close(output_pipe[1]);
exit(0);
}
void process_B(int input_pipe[], int output_pipe[])
{
int c;
char ch;
int rc;
close(input_pipe[1]);
close(output_pipe[0]);
while (read(input_pipe[0], &ch, 1) > 0) {
c = (int)ch;
if (isascii(c) && isupper(c))
c = tolower(c);
else if (isascii(c) && islower(c))
c = toupper(c);
ch = (char)c;
rc = write(output_pipe[1], &ch, 1);
if (rc == -1) {
perror("B_TO_A: write");
close(input_pipe[0]);
close(output_pipe[1]);
exit(1);
}
}
close(input_pipe[0]);
close(output_pipe[1]);
exit(0);
}
int main(int argc, char* argv[])
{
/* 2 arrays to contain file descriptors, for two pipes. */
int A_TO_B[2];
int B_TO_A[2];
int pid;
int rc,i,State;
/* first, create one pipe. */
rc = pipe(A_TO_B);
if (rc == -1) {
perror("main: pipe A_TO_B");
exit(1);
}
/* create another pipe. */
rc = pipe(B_TO_A);
if (rc == -1) {
perror("main: pipe B_TO_A");
exit(1);
}
for(i=0;i<2;i++)
{
if((pid=fork()) <0){perror("fork failed\n");};
if((i==0) && (pid ==0))
{
process_A(A_TO_B, B_TO_A);
}
else if((i==1)&&(pid==0))
{
process_B(B_TO_A, A_TO_B);
}
else if(pid>0)
{
wait( &State );
}
}
return 0;
}
问题是当我运行程序时,Son B得到Block。 我需要你们的帮助。 提前谢谢。
答案 0 :(得分:2)
好的,图表:
initially: parent process: has
B_TO_A[0] and [1] open,
has A_TO_B[0] and [1] open
fork (makes copy)
parent: child (pid==0):
B_TO_A both open, A_TO_B both open call process_A: close unwanted pipe ends, loop
call wait(), wait for one child loop reads stdin, writes one pipe, reads other pipe
if we ever get here:
fork (makes copy)
parent: child (pid==0):
B_TO_A both open, A_TO_B both open call process_B: close unwanted pipe ends, loop
parent: both ends of both pipes open
call wait(), wait for one child loop reads one pipe, writes other pipe
首先,你通常不会得到“如果我们到达这里”,因为运行process_A()
的子进程在循环中运行,直到stdin上的EOF(如果首先发生)或其中一个管道读/写调用失败(例如,由于input_pipe[0]
上的EOF)。由于父进程仍在wait()调用中等待,并且两个管道的两端都打开,管道上没有EOF(在读取所有编写器写入的所有数据之后,管道上出现EOF,并且{{1写端的s已经关闭)。所以到达那里的唯一方法是在stdin上点击EOF,这样dup
循环就不会运行了。
其次,如果你再次开始分叉并做while
,那个孩子也将永远等待,因为它正在读取的管道的一个写端仍然是......在父母中!父母不会关闭它,因为父母将永远等待process_B()
。
一般来说,你需要做的是:
wait
process_A()
错误处理有点乱,因为如果你不能启动第二个孩子你必须做某事(例如process_B()
第一个孩子)。所以你需要知道你走了多远。你仍然可以循环到fork两次,但你不能在循环中kill()
,并且只需要绕循环两次,每次都执行相当不同的步骤,你也可以在没有循环的情况下全部写出来