15

Macでメモリマップファイルを再マップする方法を見つけようとしています(利用可能なスペースを拡張したい場合)。

Linux の世界の友人が持っているのを見ますmremapが、私の Mac のヘッダーにはそのような機能が見つかりません。/Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h次のものがあります。

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • でもいいえmremap

man mremap私の恐れを確認します。

現在、マップされたファイルのサイズを変更したい場合は、ロードされたすべてのページを無効にする必要がありますmunmapmmmapもっと良い方法があるはずです。もちろん?

Mac OS X と Linux で動作するコードを書こうとしています。必要に応じて、それぞれのケースで最適な関数を使用するようにマクロを設定することもできますが、適切に実行することをお勧めします。

4

4 に答える 4

4

マップを縮小する必要がある場合は、munmap削除したい最後の部分だけです。

地図を拡大する必要がある場合は、古い地図のすぐ上の住所mmapに適切なオフセットを適用できますがMAP_FIXED、既に存在する他のものに地図を重ねないように注意する必要があります...

上記の取り消し線の下のテキストはひどい考えです。MAP_FIXEDターゲットアドレスにあるものをすでに知っていて、それをアトミックに置き換えたい場合を除き、根本的に間違っています。アドレス範囲が空いている場合に何か新しいものを日和見的にマッピングしようとしている場合は、要求されたアドレスを使用する必要がありますが、使用mmapない MAP_FIXEDで、それが成功して要求されたアドレスが得られるかどうかを確認してください。成功したが別のアドレスを使用している場合は、作成したばかりの新しいマッピングをアンマップし、要求されたアドレスでの割り当てが不可能であると想定します。

于 2010-12-29T04:37:59.450 に答える
1

十分な大きさのチャンク (たとえば 64 MB ですが、成長の速さによって異なります) で拡張する場合、古いマップを無効にするコストは無視できます。いつものように、問題を想定する前にベンチマークを行ってください。

于 2011-04-02T20:33:52.900 に答える
0

ファイルを大きなサイズに ftruncate して (ホールを作成)、そのすべてを mmap することができます。ファイルが永続的である場合は、マッピングに書き込むのではなく、書き込み呼び出しで穴を埋めることをお勧めします。そうしないと、ファイルのブロックがディスク上で不必要に断片化される可能性があります。

于 2010-08-19T21:15:07.333 に答える
0

メモリ マッピングの経験はありませんが、何も失うことなくマッピングを拡張する手段として、同じファイルを一時的に 2 回マッピングできるようです。

int main() {
    int fd;
    char *fp, *fp2, *pen;

      /* create 1K file */
    fd = open( "mmap_data.txt", O_RDWR | O_CREAT, 0777 );
    lseek( fd, 1000, SEEK_SET );
    write( fd, "a", 1 );

      /* map and populate it */
    fp = mmap( NULL, 1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
    pen = memset( fp, 'x', 1000 );

      /* expand to 8K and establish overlapping mapping */
    lseek( fd, 8000, SEEK_SET );
    write( fd, "b", 1 );
    fp2 = mmap( NULL, 7000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );

      /* demonstrate that mappings alias */
    *fp = 'z';
    printf( "%c ", *fp2 );

      /* eliminate first mapping */
    munmap( fp, 1000 );

      /* populate second mapping */
    pen = memset( fp2+10, 'y', 7000 );

      /* wrap up */
    munmap( fp2, 7000 );
    close( fd );
    printf( "%d\n", errno );
}

出力はzxxxxxxxxxyyyyyy....です。

たぶん、これをガンガン使うと、 よりも早くアドレス空間が不足する可能性がありますmremap。しかし、どちらの方法でも保証されるものは何もなく、一方で安全である可能性もあります.

于 2010-08-19T19:45:44.703 に答える