1

私はこのコードを持っています:最初の子が2番目の子にデータを送信し、2番目の子がfscanfを実行し、読み取りができないためにスタックしたときにプログラムがスタックしました。理由がわかりません。フラッシュがデータを転送することを確認する方法を見つけるのを手伝ってください。

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を使用する場合、パターンは 2 つの入力ディレクティブで構成されます。これは着信番号に一致し、次に着信改行 (空白) に一致します。この時点で、はさらに入力を探し続けます。これ以上入力が送信されないため、プログラムはブロックされます。fscanf"%u\n"%u\nfscanf

そして、なぜfscanfgo はさらに入力を探すために戻るのでしょうか? 上記の最初の引用は、終了の 2 つの条件を示しています。fifo はまだ開いているので、それ以上の入力がないことはわかりません。そのため、条件が満たされていないfscanfか、ディレクティブが一致しない場合は返されます。しかし、それはまだ起こっていません。

修正に関する限り\n、パターンからを削除するfscanfだけで十分です。マニュアルページには、次のことが記載されています。

ほとんどの変換では、最初の空白文字が破棄されます...

これは の場合に当てはまります。したがって、 のパターンを使用して%uを送信すると、 はディレクティブで一致の失敗を引き起こし、 が返されます。これにより入力バッファに が残りますが、次の の呼び出しで最初の空白 (改行) が破棄され、すべて問題なく動作するはずです。%u\nfscanf%u\n%ufscanf\nfscanf

于 2015-07-22T13:55:22.320 に答える