4

flags を使用してファイルを開くユーザーレベルのプログラムがありますO_WRONLY|O_SYNC。このプログラムは、それぞれ 256 バイト以上のデータをファイルに書き込もうとする 256 個のスレッドを作成します。合計で 1280000 件のリクエストが必要で、合計で約 300 MB のデータになります。1280000 件のリクエストが完了すると、プログラムは終了します。

pthread_spin_trylock()完了したリクエストの数を追跡する変数をインクリメントするために使用します。各スレッドが一意のオフセットに書き込むようにするために、pwrite()既に書き込まれた要求の数の関数としてオフセットを使用して計算します。したがって、実際にファイルに書き込むときはミューテックスを使用しません (このアプローチはデータの整合性を保証しますか?)

呼び出しがブロックされた平均時間pwrite()と対応する数値 (つまり、BIO の完全なライフサイクルの時間の尺度である平均 Q2C 時間) を使用しblktraceて確認すると、有意差。pwrite()実際、特定の BIO の平均完了時間は、通話の平均待ち時間よりもはるかに長くなります。この不一致の背後にある理由は何ですか? O_SYNCデータが返される前に実際に物理メディアに書き込まれることを保証するため、これらの数値は似ているはずではありませんか?

4

1 に答える 1

3

pwrite()アトミックであると想定されているため、そこでは安全なはずです...

open(2) のkernel.orgの man ページに関するこの情報によると、syscall と実際の BIO の間のレイテンシーの違いに関して:

POSIX は、フラグ O_SYNC、O_DSYNC、および O_RSYNC に対応する、同期 I/O の 3 つの異なるバリアントを提供します。現在 (2.6.31)、Linux は O_SYNC のみを実装していますが、glibc は O_DSYNC と O_RSYNC を O_SYNC と同じ数値にマップします。ほとんどの Linux ファイル システムは、実際には POSIX O_SYNC セマンティクスを実装していません。これは、書き込みのすべてのメタデータ更新がユーザー空間に戻るときにディスク上にあることを要求しますが、O_DSYNC セマンティクスのみを実装します。システムコールが戻るまでにディスク上にあること。

したがって、これは基本的に、O_SYNCフラグを使用すると、書き込もうとしているデータ全体をシステムコールが戻る前にディスクにフラッシュする必要はなく、ディスクから取得できるのに十分な情報だけであることを意味します...これは、ディスクに書き込む予定だったデータのバッファ全体よりもかなり少ない可能性があるため、すべてのデータの実際の書き込みは、syscall が完了した後で行われます。そして、プロセスは別のものに移りました。

于 2011-08-24T22:37:42.990 に答える