导航功能将所有输出打印两次

时间:2019-04-10 21:04:58

标签: c linux pipe fork

当我分别单独调用函数时,它们可以正常工作,只打印一次所需的消息即可。调用这两个函数会使导航将其消息打印两次。

我查找了不同的解决方案。我尝试使用fflush(stdout)无济于事,我尝试使用main中的条件来确保它们单独运行。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>
#include "RAND_API.h"
#define MAXLEN 500

void lifeSupport();
void navigation();

int main()
{


    lifeSupport();
    navigation();
    return 0;
}

void lifeSupport()
{
        //Create pipe


        ret = write( myPipe[1], lifeSup1, strlen( lifeSup1 ) + 1 );
        //sleep( getRandExponential() * 10 );
        ret = write( myPipe2[1], lifeSup2, strlen( lifeSup2 ) + 1 );
        //sleep( getSRand() * 6 );
        sleep( getRandExponential() * 5 );
        ret = write( myPipe3[1], lifeSup3, strlen( lifeSup3 ) + 1 );
        sleep( getRandExponential() * 4 );
        ret = write( myPipe4[1], lifeSup4, strlen( lifeSup4 ) + 1 );
        close( myPipe[1] );
        close( myPipe2[1] );
        close( myPipe3[1] );
        close( myPipe4[1] );
    }
    else
    {
        //wait(NULL);
        close( myPipe[1] );
        close( myPipe2[1] );
        close( myPipe3[1] );
        close( myPipe4[1] );
        ret = read( myPipe[0], buffer, MAXLEN );
        printf( "%s", buffer );
        ret = read( myPipe2[0], buffer, MAXLEN );
        printf( "%s", buffer );
        ret = read( myPipe3[0], buffer, MAXLEN );
        printf( "%s", buffer );
        ret = read( myPipe4[0], buffer, MAXLEN );
        printf( "%s", buffer );
    }

}

void navigation()
{
       //create pipe

        ret = write( apipe[1], nav1, strlen( nav1 ) + 1 );
        ret = write( apipe2[1], nav2, strlen( nav2 ) + 1 );
        //sleep( getSRand() * 6 );
        ret = write( apipe3[1], nav3, strlen( nav3 ) + 1 );

        close( apipe[1] );
        close( apipe2[1] );
        close( apipe3[1] );

    }
    else
    {
        close( apipe[1] );
        close( apipe2[1] );
        close( apipe3[1] );

        ret = read( apipe[0], buff, MAXLEN );
        printf( "%s\n", buff );

        ret = read( apipe2[0], buff, MAXLEN );
        printf( "%s\n", buff );

        ret = read( apipe3[0], buff, MAXLEN );
        printf( "%s\n", buff );

        close( apipe[0] );
        close( apipe2[0] );
        close( apipe3[0] );

    }

}

输出:

Life support system initiiated
Adjusting breathing gas levels
Adjusting enviroment
Life support system terminating
Initiating navigation system

Initiating navigation system
Making adjustments


Making adjustments
Adjustments done. Navigation system terminating.


Adjustments done. Navigation system terminating.

预期输出:

Life support system initiiated
Adjusting breathing gas levels
Adjusting enviroment
Life support system terminating
Initiating navigation system
Making adjustments

Adjustments done. Navigation system terminating.

1 个答案:

答案 0 :(得分:1)

调用lifeSupport()时,它将派生一个孩子。子级将消息写入所有myPipeX管道,父级从它们读取并打印消息,然后父级和子级都返回main()

然后,两个进程都调用navigation()。他们各自创造了另一个孩子。两个孩子写到apipeX管道,两个父母从中读取消息,并分别打印消息。因此,您从navigation()获得了所有消息的两个副本。

在每个函数中,子级应该在完成后调用exit(),而不是返回。只有父母应该返回main()