1

我有这个代码:当第一个孩子向第二个孩子发送数据时程序卡住了,第二个孩子做 fscanf 然后卡住了,因为他看不懂我找不到它的原因。请帮助我了解如何确保 fflush 将传输数据。

int main()
{
    pid_t childPid ; //Child's and father process id.
    int i ; //An index to create children in loop.
    unsigned int st_search_prime = 0 ;

    if((mkfifo(FIRST_FIFO, S_IFIFO | 0644) == FAIL && errno != EEXIST) ||
       (mkfifo(SECOND_FIFO, S_IFIFO | 0644) == FAIL && errno != EEXIST))
    {
        perror("Cannot create fifo file") ;
        exit(EXIT_FAILURE) ;
    }
    //create the children
    for(i = 0 ; i < NUM_OF_CHILDS  ; i++)
    {
        childPid = fork() ;
        if(childPid < 0)    //Fork failed.
        {
            perror("Cannot fork()") ;
            exit(EXIT_FAILURE) ;
        }
        else if(childPid == CHILD)  //child process
        {
            if(i == FIRST_SON)  //the 1st child process
                doChild1(st_search_prime) ;
            else        //the 2nd child process.
                doChild2(st_search_prime) ;
        }
    }
    //wait for the children to exit.
    for(i = 0 ; i < NUM_OF_CHILDS ; i++)
        wait(&childPid) ;

    return(EXIT_SUCCESS) ;
}

void doChild1(unsigned int st_search_prime)
{
    int counter = 0 ; //Counter for N successfully raffle .
    FILE* fdw1 ;
    FILE* fdr2 ;

    if((!(fdw1 = fopen(FIRST_FIFO, "w"))))
    {
        perror("Cannot open fifo file for w/r") ;
        exit(EXIT_FAILURE) ;
    }

    if((!(fdr2 = fopen(SECOND_FIFO, "r"))))
    {
        perror("Cannot open fifo file for w/r") ;
        exit(EXIT_FAILURE) ;
    }

    for(; counter < N ; counter++)
    {
        st_search_prime = raffle_prime(st_search_prime) ;
        **fprintf(fdw1, "%u\n", st_search_prime) ;
        fflush(fdw1) ;**
        printf("%u\n", st_search_prime) ;
        fscanf(fdr2, "%u\n", &st_search_prime) ;
    }
    fclose(fdw1) ;
    fclose(fdr2) ;

    exit(EXIT_SUCCESS) ;
}

void doChild2(unsigned int st_search_prime)
{
    int counter = 0 ; //Counter for N successfully raffle .
    FILE* fdw2 ;
    FILE* fdr1 ;

    if((!(fdr1 = fopen(FIRST_FIFO, "r"))))
    {
        perror("Cannot open fifo file for w/r") ;
        exit(EXIT_FAILURE) ;
    }
    if(!(fdw2 = fopen(SECOND_FIFO, "w")))
    {
        perror("Cannot open fifo file for w/r") ;
        exit(EXIT_FAILURE) ;
    }

    for(; counter < N ; counter++)
    {
        **fscanf(fdr1, "%u\n", &st_search_prime);**
        st_search_prime = raffle_prime(st_search_prime) ;
        fprintf(fdw2, "%u\n", st_search_prime) ;
        fflush(fdw2) ;
        printf("%u\n", st_search_prime) ;
    }
    fclose(fdr1) ;
    fclose(fdw2) ;

    exit(EXIT_SUCCESS) ;
}
4

2 回答 2

0

尝试添加通话setlinebuf(fdw1)- 这应该会有所帮助。

此调用在换行符后强制刷新缓冲区。您也可以使用setvbuf()with 参数_IOLBF来获得相同的效果或_IONBF完全禁用缓冲。

于 2012-12-08T10:00:50.283 回答
0

我相信的问题是\n在你的fscanf模式中使用。手册页fscanf说:

格式字符串由一系列指令组成,这些指令描述了如何处理输入字符序列。如果指令处理失败,则不再读取输入,并且 scanf() 返回。“失败”可以是以下任何一种:输入失败,意味着输入字符不可用,或匹配失败,意味着输入不合适......

此外,根据指令,我们有:

一系列空白字符(空格、制表符、换行符等;参见 isspace(3))。该指令匹配输入中任意数量的空白,包括无空白。

因此,当doChild2您使用该fscanf模式时,"%u\n"该模式由两个输入指令组成,一个%u匹配传入的数字,然后\n匹配传入的换行符(空白)。此时,fscanf将继续寻找更多输入,因为没有更多输入被发送,导致您的程序阻塞。

为什么fscanf要回去寻找更多的输入?上面的第一个引用告诉我们终止的两个条件,要么没有更多的输入;要么 那么先进先出仍然是打开的,所以我们不知道没有更多的输入,所以条件不满足,或者,fscanf如果指令匹配失败,将返回;但这还没有发生。

就修复而言,\nfscanf模式中删除应该就足够了。手册页告诉我们:

大多数转换会丢弃初始空白字符...

就是这种情况%u,因此如果您使用 的 模式发送%u\nfscanf使用 的模式%u则将导致指令\n匹配失败,从而导致返回。这会将 保留在输入缓冲区中,但是,下一次调用将丢弃初始空白(换行符),一切都应该很好。%ufscanf\nfscanf

于 2015-07-22T13:55:22.320 回答