使用管道在两个子进程之间进行通信

我正在尝试编写产生两个子进程的代码,这些进程通过管道相互发送消息然后终止。 但是,当我运行以下代码时,只有child2打印出问候语,但是子1仍然会打印从子2获取的消息,而子节点1则不会。

有人知道我的方法有什么问题吗?

#include  #include  #include  #include  #include  int main(int argc, char** argv) { char chld_1_send[20] = "hello from child 1"; char chld_1_recv[20]; char chld_2_send[20] = "hi from child 2"; char chld_2_recv[20]; int chld_1_outgoing[2]; int chld_2_outgoing[2]; pipe(chld_1_outgoing); pipe(chld_2_outgoing); int chld_1_status, chld_2_status; pid_t chld_1, chld_2; chld_1 = fork(); if(chld_1 == 0) { chld_2 = fork(); } if(chld_1 == 0 && chld_2 == 0) { printf("parent [pid:%d] waiting on both children to finish\n", getpid()); while(wait(&chld_1_status) != chld_1 && wait(&chld_2_status) != chld_2) {} printf("done waiting\n"); } else if(chld_1 != 0 && chld_2 == 0) { printf("this is child 1 [pid:%d] with parent [pid:%d]\n", getpid(), getppid()); write(chld_1_outgoing[1], chld_1_send, strlen(chld_1_send)); while(read(chld_1_outgoing[0], &chld_1_recv, sizeof(chld_2_recv)) < 0) {} printf("child 2 said '%s'\n", chld_1_recv); exit(0); } else if(chld_2 != 0 && chld_1 == 0) { printf("this is child 2 [pid:%d] with parent [pid:%d]\n", getpid(), getppid()); write(chld_2_outgoing[1], chld_2_send, strlen(chld_2_send)); while(read(chld_2_outgoing[0], &chld_2_recv, sizeof(chld_2_recv)) < 0) {} printf("child 1 said '%s'\n", chld_2_recv); exit(0); } printf("both children have terminated successfully\n"); return 0; } 

但是,运行此命令会将此打印到终端并进入无限循环:

 $ this is child 2 [pid:15713] with parent [pid:1] child 1 said 'hi from child 2' parent [pid:15714] waiting on both children to finish 

以下是一个简单的例子,肯定可以改进,但应该让你开始。 另请关注Link1和Link2以获取更多信息。

 #include  #include  #include  #include  #include  /* max receiving buffer size; Note: no check or enforcement is made on this value*/ #define BUF_SIZE 256 int main() { int pfd1[2]; int pfd2[2]; ssize_t numRead = -1; /* Note: working under the assumption that the messages are of equal length*/ const char* messageOne = "Hello from child ONE.\n"; const char* messageTwo = "Hello from child TWO.\n"; const unsigned int commLen = strlen(messageOne) + 1; char buf[BUF_SIZE]; if (pipe(pfd1) == -1) { printf("Error opening pipe 1!\n"); exit(1); } if (pipe(pfd2) == -1) { printf("Error opening pipe 2!\n"); exit(1); } printf("Piped opened with success. Forking ...\n"); // child 1 switch (fork()) { case -1: printf("Error forking child 1!\n"); exit(1); case 0: printf("\nChild 1 executing...\n"); /* close reading end of first pipe */ if (close(pfd1[0]) == -1) { printf("Error closing reading end of pipe 1.\n"); _exit(1); } /* close writing end of second pipe */ if (close(pfd2[1]) == -1) { printf("Error closing writing end of pipe 2.\n"); _exit(1); } /* write to pipe 1 */ if (write(pfd1[1], messageOne, commLen) != commLen) { printf("Error writing to pipe 1.\n"); _exit(1); } if (close(pfd1[1]) == -1) { printf("Error closing writing end of pipe 1.\n"); _exit(1); } /* reding from pipe 2 */ numRead = read(pfd2[0], buf, commLen); if (numRead == -1) { printf("Error reading from pipe 2.\n"); _exit(1); } if (close(pfd2[0]) == -1) { printf("Error closing reding end of pipe 2.\n"); _exit(1); } printf("Message received child ONE: %s", buf); printf("Exiting child 1...\n"); _exit(0); default: break; } // child 2 switch (fork()) { case -1: printf("Error forking child 2!\n"); exit(1); case 0: printf("\nChild 2 executing...\n"); /* close reading end of second pipe */ if (close(pfd2[0]) == -1) { printf("Error closing reading end of pipe 2.\n"); _exit(1); } /* close writing end of first pipe */ if (close(pfd1[1]) == -1) { printf("Error closing writing end of pipe 1.\n"); _exit(1); } /* read from the first pipe */ if (read(pfd1[0], buf, commLen) == -1) { printf("Error reading from pipe 1.\n"); _exit(EXIT_FAILURE); } if (close(pfd1[0]) == -1) { printf("Error closing reading end of pipe 1.\n"); _exit(EXIT_FAILURE); } /* write to the second pipe */ if (write(pfd2[1], messageTwo, commLen) != commLen) { printf("Error writing to the pipe."); _exit(EXIT_FAILURE); } if (close(pfd2[1]) == -1) { printf("Error closing writing end of pipe 2."); _exit(EXIT_FAILURE); } printf("Message received child TWO: %s", buf); printf("Exiting child 2...\n"); _exit(EXIT_SUCCESS); default: break; } printf("Parent closing pipes.\n"); if (close(pfd1[0]) == -1) { printf("Error closing reading end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(pfd2[1]) == -1) { printf("Error closing writing end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(pfd2[0]) == -1) { printf("Error closing reading end of the pipe.\n"); exit(EXIT_FAILURE); } if (close(pfd1[1]) == -1) { printf("Error closing writing end of the pipe.\n"); exit(EXIT_FAILURE); } printf("Parent waiting for children completion...\n"); if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } if (wait(NULL) == -1) { printf("Error waiting.\n"); exit(EXIT_FAILURE); } printf("Parent finishing.\n"); exit(EXIT_SUCCESS); } 

您的逻辑是向后的,用于确定给定的进程是父进程还是子进程。 孩子从fork得到0 ,父母得到孩子的pid。 据推测,您希望两个孩子都拥有相同的父母,在这种情况下,第一个应该是:

 if(chld_1 != 0) 

并且,父级应该是chld_1chld_2都非零的过程:

 if(chld_1 != 0 && chld_2 != 0) 

此外,您应该对两个fork进行错误检查(返回-1表示错误)。