Вопрос

Я пытаюсь выяснить, как переназначить файлы с отображением в памяти на Mac (когда я хочу расширить доступное пространство).

Я вижу, что у наших друзей в мире Linux есть mremap но я не могу найти такой функции в заголовках на моем Mac. /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h имеет следующее:

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • но нет mremap

man mremap подтверждает мои опасения.

В настоящее время мне приходится munmap и mmmap если я хочу изменить размер отображаемого файла, что предполагает аннулирование всех загруженных страниц.Должен быть способ получше.Наверняка?

Я пытаюсь написать код, который будет работать на Mac OS X и Linux.Я мог бы согласиться на то, чтобы макрос использовал наилучшую функцию в каждом конкретном случае, если я имел но я бы предпочел сделать это как следует.

Это было полезно?

Решение

Вы можете обрезать файл до большого размера (создав отверстие) и ммапировать весь его.Если файл является постоянным, я рекомендую заполнить пробел вызовами write, а не записью в сопоставлении, так как в противном случае блоки файла могут оказаться излишне фрагментированными на диске.

Другие советы

Если вам нужно уменьшить карту, просто munmap часть в конце, которую вы хотите удалить.

Если вам нужно увеличить карту, вы можете mmap правильное смещение с помощью MAP_FIXED по адресам, расположенным чуть выше старой карты, но вам нужно быть осторожным, чтобы не нанести на карту что-то еще, что уже есть...

Приведенный выше текст под зачеркиванием - ужасная идея; MAP_FIXED это в корне неверно, если только вы уже не знаете, что находится по целевому адресу, и не хотите атомарно заменить его.Если вы пытаетесь оппортунистически сопоставить что-то новое, если диапазон адресов свободен, вам необходимо использовать mmap с запрошенным адресом, но без MAP_FIXED и посмотрите, сработает ли это успешно и выдаст ли вам запрошенный адрес;если это удастся, но с другим адресом, вам захочется отменить новое сопоставление, которое вы только что создали, и предположить, что распределение по запрошенному адресу было невозможно.

Если вы расширяетесь достаточно большими фрагментами (скажем, 64 МБ, но это зависит от того, насколько быстро он растет), то стоимость аннулирования старой карты незначительна.Как всегда, проведите тест, прежде чем предполагать наличие проблемы.

У меня нет опыта работы с сопоставлением памяти, но, похоже, вы можете временно сопоставить один и тот же файл дважды, чтобы расширить сопоставление без потери чего-либо.

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