两个子之间的通信与处理管道 [英] communicating between two child processes with pipes

查看:126
本文介绍了两个子之间的通信与处理管道的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写code,它滋生了对方发送的消息通过管道,然后终止两个子进程。然而,当我运行下面的code只打印的child2这是问候,但孩子还是1打印从孩子2得到消息,其中儿童1没有。

有谁知道这有什么错我的方法?

 的#include<&string.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&;&unistd.h中GT;INT主(INT ARGC,字符** argv的){
    焦炭chld_1_send [20] =你好,从孩子1;
    炭chld_1_recv [20];
    焦炭chld_2_send [20] =喜从小孩2;
    炭chld_2_recv [20];    INT chld_1_outgoing [2];
    INT chld_2_outgoing [2];    管(chld_1_outgoing);
    管(chld_2_outgoing);    INT chld_1_status,chld_2_status;
    将为pid_t chld_1,chld_2;    chld_1 =叉();    如果(chld_1 == 0){
        chld_2 =叉();
    }    如果(chld_1 == 0安培;&安培; chld_2 == 0){
        的printf(父[PID:%d个]等待两个孩子完成\\ N,GETPID());        而(等待(安培; chld_1_status)= chld_1和放大器;!&放大器;等待(安培; chld_2_status)= chld_2!){}        输出(等待做\\ n);
    }
    否则,如果(chld_1 = 0&安培;!&安培; chld_2 == 0){
        的printf(这孩子1 [PID:%d个]与父母[PID:%D]。\\ n,GETPID(),getppid());        写(chld_1_outgoing [1],chld_1_send,strlen的(chld_1_send));
        而(读(chld_1_outgoing [0],&放大器; chld_1_recv,sizeof的(chld_2_recv))小于0){}        的printf(孩子说:2'%s'的\\ n,chld_1_recv);
        出口(0);
    }
    否则,如果(chld_2 = 0&安培;!&安培; chld_1 == 0){
        的printf(这是孩子2 [PID:%d个]与父母[PID:%D]。\\ n,GETPID(),getppid());        写(chld_2_outgoing [1],chld_2_send,strlen的(chld_2_send));
        而(读(chld_2_outgoing [0],&放大器; chld_2_recv,sizeof的(chld_2_recv))小于0){}        的printf(子1说:%s的\\ n,chld_2_recv);        出口(0);
    }    的printf(两个孩子都成功终止的\\ n);    返回0;
}

不过,运行该命令打印出该终端并进入一个无限循环:

  $这是孩子2 [PID:15713]与父母[PID:1]
孩子1说:从孩子2'
父[PID:15714]等待两个孩子完成


解决方案

下面是一个简单的例子,这肯定可以改善,但应该让你开始。
也跟着<一个href=\"http://stackoverflow.com/questions/2784500/how-to-send-a-simple-string-between-two-programs-using-pipes\">Link1和链路2 了解更多信息。

 的#include&LT;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / wait.h&GT;
#包括LT&;&unistd.h中GT;/ *最大接收缓冲区的大小;注:无校验或执行这个值做* /
#定义BUF_SIZE 256诠释的main()
{
    INT PFD1 [2];
    INT PFD2 [2];    ssiz​​e_t供numRead = -1;
    / *注:假设条件下工作的消息
       长度相等的* /
    为const char * MessageOne的=你好,从小孩ONE \\ N的;
    为const char * messageTwo =你好,从儿童两个\\ n;    const的无符号整型commLen = strlen的(MessageOne的)+ 1;    烧焦的buf [BUF_SIZE]    如果(管(PFD1)== -1)
    {
        的printf(错误打开管道1 \\ n!);
        出口(1);
    }    如果(管(PFD2)== -1)
    {
        的printf(错误开幕管2 \\ n!);
        出口(1);
    }    的printf(管道式成功的分岔...... \\ n开);    //子1
    开关(叉())
    {
        情况1:
            的printf(错误分叉儿1 \\ n!);
            出口(1);        情况下0:
            的printf(\\ nChild 1执行... \\ n);
            / *细读第一末端治理* /
            如果(接近(PFD1 [0])== - 1)
            {
                的printf(管子错误关闭读终1. \\ n);
                _exit(1);
            }
            / *第二个管道*接近书写端/
            如果(接近(PFD2 [1])== - 1)
            {
                的printf(错误收盘写作管2 \\ n结束);
                _exit(1);
            }            / *写管道1 * /
            如果(写(PFD1 [1],MessageOne的,commLen)!= commLen)
            {
                的printf(写入管道1 \\ n);
                _exit(1);
            }            如果(接近(PFD1 [1])== - 1)
            {
                的printf(错误闭幕写管道1 \\ n结束);
                _exit(1);
            }            / *从管2雷丁* /
            numRead =读(PFD2 [0],BUF,commLen);
            如果(numRead == -1)
            {
                的printf(错误从管2 \\ n读);
                _exit(1);
            }            如果(接近(PFD2 [0])== - 1)
            {
                的printf(管子错误关闭雷丁结束2 \\ n);
                _exit(1);
            }            的printf(收到消息的孩子之一:%的,BUF);
            的printf(退出子1 ... \\ n);
            _exit(0);        默认:
            打破;
    }    //子2
    开关(叉())
    {
        情况1:
            的printf(错误分叉儿2 \\ n!);
            出口(1);
        情况下0:
            的printf(\\ nChild 2执行... \\ n);
            / *细读第二管道的终点* /
            如果(接近(PFD2 [0])== - 1)
            {
                的printf(管子错误关闭读终2. \\ n);
                _exit(1);
            }
            / *第一管*接近书写端/
            如果(接近(PFD1 [1])== - 1)
            {
                的printf(错误闭幕写管道1 \\ n结束);
                _exit(1);
            }            / *从第一个管道中读取* /
            如果(读(PFD1 [0],buf中,commLen)== - 1)
            {
                的printf(错误从管材1 \\ n读);
                _exit(EXIT_FAILURE);
            }            如果(接近(PFD1 [0])== - 1)
            {
                的printf(管子错误关闭读终1. \\ n);
                _exit(EXIT_FAILURE);
            }            / *写入到第二管* /
            如果(写(PFD2 [1],messageTwo,commLen)!= commLen)
            {
                的printf(写入到管道。);
                _exit(EXIT_FAILURE);
            }            如果(接近(PFD2 [1])== - 1)
            {
                的printf(错误收盘写作管2结束);
                _exit(EXIT_FAILURE);
            }            的printf(消息接收到的子二:%S,BUF);
            的printf(退出子2 ... \\ n);
            _exit(EXIT_SUCCESS);        默认:
            打破;
    }    的printf(父收盘管道\\ n);    如果(接近(PFD1 [0])== - 1)
    {
        的printf(错误关闭读管道的结束\\ n);
        出口(EXIT_FAILURE);
    }    如果(接近(PFD2 [1])== - 1)
    {
        的printf(错误关闭写管道的结束\\ n);
        出口(EXIT_FAILURE);
    }    如果(接近(PFD2 [0])== - 1)
    {
        的printf(错误关闭读管道的结束\\ n);
        出口(EXIT_FAILURE);
    }    如果(接近(PFD1 [1])== - 1)
    {
        的printf(错误关闭写管道的结束\\ n);
        出口(EXIT_FAILURE);
    }    的printf(家长等待孩子完成... \\ n);
    如果(等待(NULL)== -1)
    {
        的printf(错误等待\\ n);
        出口(EXIT_FAILURE);
    }    如果(等待(NULL)== -1)
    {
        的printf(错误等待\\ n);
        出口(EXIT_FAILURE);
    }    的printf(父精\\ n);
    出口(EXIT_SUCCESS);
}

I'm trying to write code that spawns two child processes that send each other a message over a pipe then terminate. However, when I run the following code only child2 prints it's greeting but child 1 still prints the message it gets from child 2 where child 1 doesn't.

Does anybody know what's wrong with my methodology?

#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;
}

However, running this command prints out this to the terminal and goes into an infinite loop:

$ 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

解决方案

Following is a simple example which certainly can be improved but should get you started. Also follow Link1 and Link2 for more info.

#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);
}

这篇关于两个子之间的通信与处理管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆