4

ファイルのブロックを生成する複数のスレッドがある場合、ブロックを書き出す最善の方法は何ですか?

例) 500 ブロックのファイルで作業する 5 つのスレッド。ブロック 0 は必ずしもブロック 1 の前に完了するとは限りませんが、ディスク上の出力ファイルは順序どおりである必要があります。(ブロック 0、ブロック 1、ブロック 2、.... ブロック 499)

プログラムは C++ で書かれていますが、fwrite() でファイルに「ランダム アクセス」することはできますか? ファイルはゼロから作成されます。つまり、ブロック 5 が完了しても、ブロック 1 ~ 4 がまだ完了していないため、ファイルのサイズはまだ 0 のままである可​​能性があります。ブロック 5 を直接書き出すことはできますか? (適切なfseekを使用)

このコードはパフォーマンスが重要なので、パフォーマンスを改善できるものには本当に興味があります。これは、複数のプロデューサー (ブロック ジェネレーター) と 1 つのコンシューマー (出力ライター) のシナリオのように見えます。理想的なケースは、スレッド A が前のブロックを完了したときに、次のブロックを生成し続けることができるということです。

fwrite を「ランダム」にできる場合、出力ライターは単純に出力を取得し、シークしてから書き込むことができます。ただし、この設計が大規模でうまく機能するかどうかはわかりません。

いくつかの制限

  • 各ブロックは同じサイズで、メモリ内に生成されます
  • ブロック サイズは事前にわかっていますが、ブロックの総数はわかっていません。
  • 合計サイズは数 GB です。大きい。
  • 1 つのサーバーで複数のジョブが実行されている可能性があります。各ジョブは上記で説明されています。それらには、独自の独立したジェネレーター/ライター、異なるプロセスがあります。
  • サーバーは Linux/CentOS マシンです。
4

1 に答える 1

1

各ブロックが同じサイズであり、ブロックがディスクに書き込まれる前にメモリ内に生成されると仮定すると、 と の組み合わせは完全に問題lseekありません。write

1 回の書き込みでブロック全体を書き込むことができる場合、fwrite を使用しても何の利点もありません。したがって、直接書き込みを使用してください。ただし、すべてのスレッドがブロックを共有している場合は、何らかのロック アクセス制御 (mutex) が必要になります。同じ fd -- シーク + 書き込みはアトミックに実行できないため、あるスレッドが 2 番目のスレッドが書き込みを行う直前にシークすることは望ましくありません。

これはさらに、ファイル システムが標準のファイル システムであり、風変わりな性質のものではないことを前提としています。これは、すべての入出力デバイスlseek(パイプなど) がすべてサポートされているわけではないためです。

更新: lseek はファイルの終わりを超えてシークできます。 whence パラメータ = SEEK_SET とオフセットをファイル内の絶対位置に設定するだけです (fseek には同じオプションがありますが、私は使用したことがありません)。

于 2016-05-10T21:13:47.073 に答える