Шрифт:
PROT_READ
— сегмент может читаться;
PROT_WRITE
— в сегмент можно писать;
PROT_EXEC
— сегмент может выполняться;
PROT_NONE
— к сегменту нет доступа. Параметр
flags
контролирует, как изменения, сделанные программой в сегменте, отражаются в других местах; его возможные значения приведены в табл. 3.7. Таблица 3.7
Константа | Описание |
---|---|
MAP_PRIVATE | Сегмент частный, изменения локальные |
MAP_SHARED | Изменения сегмента переносятся в файл |
MAP_FIXED | Сегмент должен располагаться по заданному адресу addr |
Функция
msync
вызывает запись изменений в части или во всем сегменте памяти обратно а отображенный файл (или считывание из файла).
#include <sys/mman.h>
int msync(void *addr, size_t len, int flags);
Корректируемая часть сегмента задается передачей начального адреса
addr
и размера len
. Параметр flags
управляет способом выполнения корректировки с помощью вариантов, приведенных в табл. 3.8. Таблица 3.8
Константа | Описание |
---|---|
MS_ASYNC | Выполнять запись асинхронно |
MS_SYNC | Выполнять запись синхронно |
MS_INVALIDATE | Обновить другие отражения этого файла так, чтобы они содержали изменения, внесенные этим вызовом |
Функция
munmap
освобождает сегмент памяти.
#include <sys/mman.h>
int munmap(void *addr, size_t len);
В программе mmap.с из упражнения 3.5 показан файл из структур, которые будут корректироваться с помощью функции
mmap
и обращений в стиле массива. Ядро Linux версий, меньших 2.0, не полностью поддерживает применение функции mmap
. Программа работает корректно в системе Sun Solaris и других системах. Упражнение 3.5. Применение функции
mmap
1. Начните с определения структуры
RECORD
и создайте NRECORDS
вариантов, в каждый из которых записывается собственный номер. Они будут добавлены в конец файла records.dat.
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
typedef struct {
int integer;
char string[24];
} RECORD;
#define NRECORDS (100)
int main {
RECORD record, *mapped;
int i, f;
FILE *fp;
fp = fopen("records.dat", "w+");
for (i=0; i<NRECORDS; i++) {
record.integer = i;
sprintf(record.string, "RECORD-%d", i);
fwrite(&record, sizeof(record), 1, fp);
}
fclose(fp);
2. Далее измените целое значение записи с 43 на 143 и запишите его в строку 43-й записи.
fp = fopen("records.dat", "r+");
fseek(fp, 43*sizeof(record), SEEK_SET);
fread(&record, sizeof(record), 1, fp);
record.integer =143;
sprintf(record.string, "RECORD-%d", record.integer);
fseek(fp, 43*sizeof(record), SEEK_SET);
fwrite(&record, sizeof(record), 1, fp);
fclose(fp);
3. Теперь отобразите записи в память и обратитесь к 43-й записи для того, чтобы изменить целое на 243 (и обновить строку записи), снова используя отображение в память.
f = open("records.dat", O_RDWR);
mapped = (RECORD *)mmap(0, NRECORDS*sizeof(record),
PROT_READ|PROT_WRITE, MAP_SHARED, f, 0);