sync、fsync、fdatasync、fflush関数の違いと使用例

1251 ワード

Linux/unixはカーネルにバッファ、キャッシュまたはページキャッシュを設け、ほとんどのディスクI/O(block device)はバッファによって行われます.データをファイルに書き込むとき、カーネルは通常、そのデータをバッファの1つにコピーします.バッファがまだいっぱい書いていない場合は、出力キューに入れません.実際のI/O操作は、書き込みが完了するのを待つか、カーネルが他のディスクブロックデータを格納するためにバッファを再利用する必要がある場合に出力キューにバッファを配置し、キューの先頭に到達するまで待機します.前述したように,カーネルがキャッシュを再利用しておらず,キャッシュがいっぱいになっていないと仮定すると,大きなバグが存在するのではないか.この問題を解決するために、updateデーモンというプロセスが定期的にsyncを実行することは許されないことは明らかだ.従来のPC機では、頻繁にディスクに書き込む問題を解決し、ディスクデータを書き込む完全性を保障しています.sync:変更されたすべてのキャッシュ領域を書き込みキューに並べ替え、実際の書き込みディスク操作の終了を待たずに戻ります.fsync関数:ファイル記述子で作成された単一のファイルにのみ機能し、ディスク操作が終了してから戻るのを待つ.fdatasync:fsyncに似ていますが、ファイルのデータ部分にのみ影響します.fsyncはまた、ファイルのプロパティを同期的に更新します.fflush:fread,fwriteなどの標準I/O関数は、メモリバッファをリフレッシュし、カーネルバッファにコンテンツを書き込み、ディスクに書き込むにはfsyncを呼び出すメモリにバッファを確立します.(fflushを呼び出してからfsyncを呼び出します.そうしないと役に立ちません).
例:
       fp = fopen(filename, "wb+");
       gettimeofday(&start, NULL); //      struct timeval start
         if (fwrite(w_buf, g_block_size, 1, fp) <= 0)  //  
            break;

        fflush(fp); //   fwrite      , flush        fp   
        fdatasync(fileno(fp));   //     ,    fsync
        gettimeofday(&end, NULL);
        write_timeuse += 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;