作者:手机用户2502863351 | 来源:互联网 | 2023-05-19 13:01
Ihavetocreate2childprocessandsenddatafromtheparenttothetwo,soIusedthepipe.我必须创建
I have to create 2 child process and send data from the parent to the two, so I used the pipe
.
我必须创建2个子进程并将数据从父进程发送到两个,所以我使用了管道。
If I just use 1 child process and 1 pipe, all works perfectly with fdopen
, fscanf
and fprintf
. Also, if I create 2 pipe and send data to a single process, still works perfectly.
如果我只使用1个子进程和1个管道,则所有这些都与fdopen,fscanf和fprintf完美配合。此外,如果我创建2个管道并将数据发送到单个进程,仍然可以正常工作。
But, if I create a second process and try to read from the second pipe
, nothing happen.
但是,如果我创建第二个进程并尝试从第二个管道读取,则没有任何反应。
for example:
例如:
int main() {
pid_t pid1, pid2;
int a[2];
pipe(a);
pid1 = fork();
if(pid1 == 0) {
char x,y;
FILE *stream;
stream = fdopen(a[0],"r");
fscanf(stream,"%c",&x);
printf("%c\n", x);
close(a[1]);
close(a[0]);
} else {
int b[2];
pipe(b);
pid2 = fork();
FILE *stream1, *stream2;
close(a[0]);
close(b[0]);
stream1 = fdopen(a[1],"w");
stream2 = fdopen(b[1],"w");
fprintf(stream1, "yo bella zio\n");
fprintf(stream2, "como estas\n");
fflush(stream1);
fflush(stream2);
close(a[1]);
close(b[1]);
waitpid (pid1, NULL, 0);
waitpid (pid2, NULL, 0);
if (pid2 == 0) {
FILE *stream;
close(b[1]);
close(a[1]);
close(a[0]);
stream = fdopen(b[0],"r");
fscanf(stream,"%c",&x);
printf("%c\n", x);
} else {
}
}
}
I really tried all combination. Declare all the pipe together, close or not close pipe. everything but nothing.
我真的尝试了所有组合。将所有管道声明在一起,关闭或不关闭管道。一切都没有。
1 个解决方案
1
This code fixes the problems identified in my comment and some stray issues.
此代码修复了我的评论中发现的问题和一些流浪问题。
#include
#include
#include
#include
#include
int main(void)
{
pid_t pid1, pid2;
int a[2];
int b[2];
pipe(a);
pid1 = fork();
if (pid1 <0)
{
fprintf(stderr, "failed to fork child 1 (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
else if (pid1 == 0)
{
close(a[1]); // Must be closed before the loop
FILE *stream = fdopen(a[0], "r");
if (stream == NULL)
{
fprintf(stderr, "failed to create stream for reading (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
int c;
while ((c = getc(stream)) != EOF)
putchar(c);
//char x;
//fscanf(stream, "%c", &x);
//printf("%c\n", x);
//close(a[0]); -- Bad idea once you've used fdopen() on the descriptor
printf("Child 1 done\n");
exit(0);
}
else
{
pipe(b);
pid2 = fork();
if (pid2 <0)
{
fprintf(stderr, "failed to fork child 2 (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
else if (pid2 == 0)
{
close(b[1]);
close(a[1]);
close(a[0]);
FILE *stream = fdopen(b[0], "r");
if (stream == NULL)
{
fprintf(stderr, "failed to create stream for reading (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
int c;
while ((c = getc(stream)) != EOF)
putchar(c);
//char x;
//fscanf(stream, "%c", &x);
//printf("%c\n", x);
printf("Child 2 done\n");
exit(0);
}
}
close(a[0]);
close(b[0]);
FILE *stream1 = fdopen(a[1], "w");
if (stream1 == NULL)
{
fprintf(stderr, "failed to create stream for writing (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
FILE *stream2 = fdopen(b[1], "w");
if (stream2 == NULL)
{
fprintf(stderr, "failed to create stream for writing (%d: %s)\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stream1, "yo bella zio\n");
fprintf(stream2, "como estas\n");
fflush(stream1); // Not necessary because fclose flushes the stream
fflush(stream2); // Not necessary because fclose flushes the stream
fclose(stream1); // Necessary because child won't get EOF until this is closed
fclose(stream2); // Necessary because child won't get EOF until this is closed
//close(a[1]); -- bad idea once you've used fdopen() on the descriptor
//close(b[1]); -- bad idea once you've used fdopen() on the descriptor
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
printf("All done!\n");
return 0;
}
Note that I changed the child processes so that (a) they explicitly exit in the code block, and (b) made their body into a loop so that all the data sent is printed. That required me to move the close(a[1])
in the first child; otherwise, the loop doesn't terminate because the o/s sees that child 1 has the descriptor open for writing.
请注意,我更改了子进程,以便(a)它们在代码块中显式退出,并且(b)将它们的主体放入循环中,以便打印所有发送的数据。这要求我在第一个孩子中移动关闭(a [1]);否则,循环不会终止,因为o / s看到子1的描述符打开以进行写入。
When executed on a Mac running macOS 10.13.6 High Sierra (GCC 8.2.0 as the compiler), I get the output:
在运行macOS 10.13.6 High Sierra(作为编译器的GCC 8.2.0)的Mac上执行时,我得到输出:
yo bella zio
Child 1 done
como estas
Child 2 done
All done!