首页 > 解决方案 > 导航功能正在打印其所有输出两次

问题描述

当我在 main 中单独调用这些函数时,它们工作正常,只需打印一次所需的消息。调用这两个函数会导致导航两次打印其消息。

我已经查找了不同的解决方案。我尝试使用 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.

标签: clinuxpipefork

解决方案


当你打电话时lifeSupport(),它会分叉一个孩子。子进程将消息写入所有myPipeX管道,父进程从它们读取并打印消息,然后父进程和子进程都返回到main().

然后两个进程都调用navigation(). 他们各自创造了另一个孩子。两个孩子写信给apipeX管道,两个父母从他们那里读,然后他们各自打印消息。所以你得到了所有来自的消息的两份副本navigation()

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


推荐阅读