gpt4 book ai didi

c - 如何使用管道将 C 中的数据从两个 child 发送到 parent ?

转载 作者:太空狗 更新时间:2023-10-29 15:40:13 25 4
gpt4 key购买 nike

我有这个任务,我必须使用 fork 创建两个 child 。 parent 必须向这些 child 发送一些信件并收到一个号码。必须使用管道进行通信。我不明白的是,为什么我的代码设法将信件发送给了 children ,但随后却什么都不做就挂起了。起初我以为是因为调用了 waitpid() 但事实并非如此。让我感到困惑的是,如果我停止读取其中一个子进程并只发送一个随机数,其他一切都会按预期工作。

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>

#define PIPE_1 0 // write to 1st child
#define PIPE_2 1 // write to parent from 1st child
#define PIPE_3 2 // write to 2nd child
#define PIPE_4 3 // write to parent from 2nd child

int main()
{
pid_t p1, p2;
int pipes[4][2];
FILE *read[4], *write[4];

int k;
for (k = 0; k < 4; k++){
if (-1 == pipe(pipes[k]) ){
perror("Error creating pipe");
exit(k+1);
}
read[k] = fdopen(pipes[k][0], "r");
write[k] = fdopen(pipes[k][1], "w");
}

if (-1 == (p1 = fork()) ){
perror("Error, failed to fork first child");
exit(5);
}

if (p1 == 0){
// 1st child
fclose(write[PIPE_1]);
int caseChange = 0;
char c;
while( fscanf(read[PIPE_1], "%c", &c) != EOF){
if (c >= 97 && c <= 122){
c -= 32;
caseChange++;
}
printf("[Process (%d)]: %c\n", getpid(), c);
}
fclose(read[PIPE_1]);

fclose(read[PIPE_2]);
fprintf(write[PIPE_2],"%d",caseChange);
fflush(write[PIPE_2]);
fclose(write[PIPE_2]);
}
else{
if (-1 == (p2 = fork()) ){
perror("Error, failed to fork second child");
exit(6);
}

if (p2 == 0){
// 2nd child
fclose(write[PIPE_3]);
int caseChange = 0;
char c;
while( fscanf(read[PIPE_3], "%c", &c) != EOF){
if (c >= 97 && c <= 122){
c -= 32;
caseChange++;
}
printf("[Process (%d)]: %c\n", getpid(), c);
}
fclose(read[PIPE_3]);

fclose(read[PIPE_4]);
fprintf(write[PIPE_4],"%d",caseChange);
fflush(write[PIPE_4]);
fclose(write[PIPE_4]);
}
else{
// Parent
//char *string = (char*) malloc(100);
char string[100];
scanf("%s", string);
int i;

int readCaseChange, caseChange = 0;

fclose(read[PIPE_1]);
for (i = 0; i < strlen(string); i+=2){
fprintf(write[PIPE_1],"%c",string[i]);
fflush(write[PIPE_1]);
}
fclose(write[PIPE_1]);

fclose(read[PIPE_3]);
for (i = 1; i < strlen(string); i+=2){
fprintf(write[PIPE_3],"%c",string[i]);
fflush(write[PIPE_3]);
}
fclose(write[PIPE_3]);

waitpid(p1, NULL, 0);
fclose(write[PIPE_2]);
fscanf(read[PIPE_2], "%d", &readCaseChange);
fclose(read[PIPE_2]);
caseChange += readCaseChange;

waitpid(p2, NULL, 0);
fclose(write[PIPE_4]);
fscanf(read[PIPE_4], "%d", &readCaseChange);
fclose(read[PIPE_4]);
caseChange += readCaseChange;

printf("%d\n", caseChange);
fflush(stdout);
}
}
return 0;
}

最佳答案

您想关闭所有未在每个子进程中使用的东西,尤其是父进程的编写器端:

// 1st child
fclose(write[PIPE_1]);
fclose(write[PIPE_3]);

// 2nd child
fclose(write[PIPE_1]);
fclose(write[PIPE_3]);

否则,子进程将保持写入端打开并阻止管道完全关闭,从而使您永远不会在子进程中获得 EOF。你部分地这样做了,但由于第二个 child 已经写 [PIPE_1] 打开,PIPE_1 从未完全关闭。

关于c - 如何使用管道将 C 中的数据从两个 child 发送到 parent ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37380010/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com