14

通常の IO API を使用して 1 つのファイルを読み書きすると、書き込みはブロック単位でアトミックであることが保証されます。つまり、私の書き込みが 1 つのブロックのみを変更する場合、オペレーティング システムは、ブロック全体が書き込まれるか、まったく書き込まれないことを保証します。

メモリ マップト ファイルで同じ効果を得るにはどうすればよいですか?

メモリ マップされたファイルは単なるバイト配列であるため、バイト配列を変更すると、オペレーティング システムはいつ書き込みが「完了」したと見なされるかを知る方法がないため、(可能性が低いとしても) メモリをスワップ アウトする可能性があります。ブロック書き込み操作の途中で、実際には半分のブロックを書き込みます。

ある種の「クリティカル セクションに入る/残す」、または書き込み中にファイルのページをメモリに「固定」する方法が必要です。そのようなものは存在しますか?もしそうなら、それは一般的なPOSIXシステムとWindowsで移植可能ですか?

4

2 に答える 2

5

日記をつけるテクニックしかないようです。同じファイルに書き込む複数のアプリでこれがどのように機能するかはわかりません。Cassandra プロジェクトには、ジャーナルでパフォーマンスを得る方法に関する優れた記事があります。重要なことは、ジャーナルが肯定的なアクションのみを記録することです (私の最初のアプローチは、各書き込みのプレイメージをジャーナルに書き込んでロールバックできるようにすることでしたが、非常に複雑になりました)。

したがって、基本的にメモリ マップト ファイルtransactionIdのヘッダーには[header[cksum]] [header[cksum]]. 最初のチェックサムが失敗した場合は、2 番目を使用します。

日誌は次のようになります。

[beginTxn[txnid]] [offset, length, data...] [commitTxn[txnid]]

大きくなりすぎるまでジャーナルレコードを追加し続け、ある時点でロールオーバーします。プログラムを起動すると、ファイルのトランザクション ID がジャーナルの最後のトランザクション ID にあるかどうかを確認します。そうでない場合は、ジャーナル内のすべてのトランザクションを再生して同期します。

于 2010-10-25T16:41:08.987 に答える