質問

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で動作するコードを作成しようとしています。私は、マクロが各ケースで最適な関数を使用するために落ち着くことができました 持っていました しかし、私はむしろそれを適切にしたいです。

役に立ちましたか?

解決

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

他のヒント

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

マップを拡大する必要がある場合は、 mmap 適切なオフセット MAP_FIXED 古いマップのすぐ上のアドレスには、すでにそこにある他の何かをマッピングしないように注意する必要があります...

ストライクアウト下の上記のテキストはひどいアイデアです。 MAP_FIXED ターゲットアドレスにあるものを既に知っていて、原子的に置き換えたい場合を除き、根本的に間違っています。アドレス範囲が無料の場合、日和見的に新しいものをマッピングしようとしている場合は、使用する必要があります mmap 要求された住所がありますが それなし MAP_FIXED そして、それが成功し、要求された住所を提供するかどうかを確認します。それが成功したが、別のアドレスを使用しても、作成したばかりの新しいマッピングをアンマップして、要求されたアドレスでの割り当てが不可能であると仮定することをお勧めします。

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

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

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. 。しかし、どちらの方法でも保証されておらず、一方で同じように安全である可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top