我正在尝试编写生成两个子进程的代码,这些进程通过管道互相发送消息然后终止。但是,当我运行以下代码时,只有child2打印出它的问候语,但是子1仍然会打印从子2获取的消息,而子节点1则没有。
有人知道我的方法有什么问题吗?
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
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
答案 0 :(得分:2)
以下是一个简单的例子,当然可以改进,但应该让你开始。 另请关注Link1和Link2了解详情。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/* 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);
}
答案 1 :(得分:0)
您的逻辑是向后的,用于确定给定流程是父流还是子流。孩子从0
获得fork
,父母获得孩子的pid。据推测,您希望两个孩子都拥有相同的父母,在这种情况下,第一个if
应该是:
if(chld_1 != 0)
而且,父级应该是chld_1
和chld_2
都非零的过程:
if(chld_1 != 0 && chld_2 != 0)
此外,您应该对fork
进行错误检查(返回-1表示错误)。