Отображение файла в память и запись в конец файла - PullRequest
1 голос
/ 02 июня 2019

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

Я вручную создал файл с vim и записал туда 2 байта:

$ cat test_mmap
aa

Тогда я написал 2 очень простые программы.

Первая программа отображает файл и изменяет сопоставление без msync и munmap.

writer.c:

int main(void){
    int fd = open("/tmp/test_mmap", O_CREAT | O_RDWR, S_IRWXU);
    char *mapped_region = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_WRITE, MAP_SHARED, fd, 0);
    mapped_region[0] = '0';
    mapped_region[1] = '1';
    mapped_region[2] = '2';
    mapped_region[3] = '3';
    mapped_region[4] = '4';
    mapped_region[5] = '5';
}

Второй читает карту.

reader.c

int main(void){
    int fd = open("/tmp/test_mmap", O_CREAT | O_RDWR, S_IRWXU);
    char *mapped_region = mmap(NULL, sysconf(_SC_PAGESIZE), PROT_WRITE, MAP_SHARED, fd, 0);
    printf("%c\n", mapped_region[0]);
    printf("%c\n", mapped_region[1]);
    printf("%c\n", mapped_region[2]);
    printf("%c\n", mapped_region[3]);
    printf("%c\n", mapped_region[4]);
    printf("%c\n", mapped_region[5]);
}

Итак, я побежал

$ ./writer && ./reader && cat /tmp/test/test_mmap
0
1
2
3
4
5
012

Это означает, что любые данные, записанные за пределами файла, сохраняются в отображении в течение некоторого времени (хотя они не записываются в файл), и если другой процесс, следовательно, отображает ту же область, данные, записанные за пределами, не обнуляются как указано в man-странице :

Файл отображается кратно размеру страницы. Для файла, который не кратный размеру страницы, оставшаяся память обнуляется, когда сопоставлены и записи в этот регион не записываются в файл.

Запуск считывателя с perf -e major-faults ./reader показывает, что

0      major-faults                                                

означает, что никакие страницы не читаются с диска. Также, глядя на /proc/<pid_writer>/smaps, я заметил, что страница помечена как грязная и закрытая (даже если отображение было создано с флагом MAP_SHARED):

7fc80f279000-7fc80f27a000 -w-s 00000000 fd:00 6057290   /tmp/test_mmap
Shared_Clean:          0 kB                                                                                                                                                                                        
Shared_Dirty:          0 kB                                                                                                                                                                                        
Private_Clean:         0 kB                                                                                                                                                                                        
Private_Dirty:         4 kB                                                                                                                                                                                        

Если через некоторое время я запустил процесс чтения (какое время требуется для ожидания?), Я заметил, что

$ ./reader
0
1
2

Вопрос: Правильно ли и где-то задокументировано, что если один процесс изменяет отображение за концом файла, страница помечается как грязная и до тех пор, пока страница грязная и другой процесс отображает ту же область того же файла, данные, записанные ранее процессом, не обнуляются и не сохраняются как некоторое время?

1 Ответ

1 голос
/ 04 июня 2019

Окончательная ссылка в этих вопросах - это POSIX, который в своем разделе обоснования для mmap должен сказать:

Функция mmap () может использоваться для отображения области памяти, которая больше чемтекущий размер объекта. [... пропустить обсуждение отправки SIGBUS, если это возможно, то есть при доступе к странице за концом файла ...] записанные данные могут быть потеряны, а прочитанные данные могут не отражать фактические данные в объекте.

Итак, POSIX говорит, что это может привести к потере данных.Кроме того, переносимость в лучшем случае сомнительна (подумайте о системах без MMU, взаимодействии с огромными страницами, платформах с различными размерами страниц ...)

...