2

固定サイズのファイルがあります。ファイルは、サイズ = N * getpagesize() に ftruncate() されています。ファイルには固定サイズのレコードがあります。ファイル全体を mmap(...MAP_SHARED...) でマップし、レコードをランダムに変更する (配列のようにアクセスする) ライター プロセスがあります。mmap(...MAP_SHARED...) も行うリーダープロセスがあります。ここで、リーダー プロセスは、ライター プロセスがランダム レコードに書き込むため、マッピングで変更されたページを特定する必要があります。ユーザー空間でそれを行う方法はありますか? 私は Linux を使用しています - x86_64。プラットフォーム固有のコード/ハックは大歓迎です。お時間をいただきありがとうございます。

編集: ライター プロセスのコードを変更して、何らかの方法で変更されたレコードを示す自由はありません。

4

2 に答える 2

5

関連ドキュメント:

  1. http://lwn.net/Articles/230975/
  2. https://www.kernel.org/doc/Documentation/vm/pagemap.txt

    • 仮想ページの数を決定し (つまり、4096 で割ります)、8 を掛けて、その位置をシークします。/proc/*/pagemap
    • 8 バイトを読み取ります。これはページ フレーム番号 (PFN) です。
    • を開き/proc/kpageflags、PFN にシークし、8 バイトを読み取ります
    • フラグが設定されている場合DIRTY、ページはダーティ (つまり、ライターが書き込み済み) です。
    • マップされたファイルの各ページに対して繰り返します
于 2013-07-17T16:41:59.853 に答える
2

それは非常に醜いものになるでしょう。ほとんどの場合、これを行う価値はありません。このコーナーにあなたを描いたものは何でも変えたほうがよいでしょう。

ロックで保護された共有ビットマップを使用できます。ライターは各ページを保護します。保護されたページに書き込むと、フォールトします。フォールトをキャッチし、ページの保護を解除し、ビットマップをロックして、ビットマップ内のそのビットに対応するビットを設定する必要があります。これにより、ページが変更されたことを読者に伝えることができます。

リーダーは次のように動作します (これは苦痛な部分です)。

  1. ビットマップをロックします。

  2. 変更されたページのリストを作成します。

  3. 変更されたページのリストをライターに伝えます。ライターはそれらのページを再度保護し、ビットマップ内のビットをクリアする必要があります。ライターは、読み取りを開始しないと変更が失われる前に、リーダーがこれを完了するまで待機する必要があります。

  4. 読者は変更されたページを読むことができます。

于 2012-08-24T13:25:57.337 に答える