如何使用管道将C中的数据从两个子节点发送到父节点?
发布时间:2020-12-16 07:16:33 所属栏目:百科 来源:网络整理
导读:我有这个任务,我必须使用fork创建两个孩子.父母必须向这些孩子发送一些信件并收回一个号码.沟通必须使用管道完成. 我无法弄清楚的是为什么我的代码设法将这些信件发送给孩子们,然后只是挂着什么都不做.起初我以为是因为waitpid()调用,但似乎并非如此.令我感
我有这个任务,我必须使用fork创建两个孩子.父母必须向这些孩子发送一些信件并收回一个号码.沟通必须使用管道完成.
我无法弄清楚的是为什么我的代码设法将这些信件发送给孩子们,然后只是挂着什么都不做.起初我以为是因为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)]: %cn",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) != EOF){ if (c >= 97 && c <= 122){ c -= 32; caseChange++; } printf("[Process (%d)]: %cn",c); } fclose(read[PIPE_3]); fclose(read[PIPE_4]); fprintf(write[PIPE_4],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],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],string[i]); fflush(write[PIPE_3]); } fclose(write[PIPE_3]); waitpid(p1,NULL,0); fclose(write[PIPE_2]); fscanf(read[PIPE_2],&readCaseChange); fclose(read[PIPE_2]); caseChange += readCaseChange; waitpid(p2,0); fclose(write[PIPE_4]); fscanf(read[PIPE_4],&readCaseChange); fclose(read[PIPE_4]); caseChange += readCaseChange; printf("%dn",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的位置.你部分这样做,但是由于第二个孩子写了[PIPE_1],PIPE_1从未完全关闭. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |