Таблица 3.7
Константа |
Описание |
MAP_PRIVATE |
Сегмент частный, изменения локальные |
MAP_SHARED |
Изменения сегмента переносятся в файл |
MAP_FIXED |
Сегмент должен располагаться по заданному адресу addr |
Функция msync
вызывает запись изменений в части или во всем сегменте памяти обратно а отображенный файл (или считывание из файла).
#include
int msync(void *addr, size_t len, int flags);
Корректируемая часть сегмента задается передачей начального адреса addr
и размера len
. Параметр flags
управляет способом выполнения корректировки с помощью вариантов, приведенных в табл. 3.8.
Таблица 3.8
Константа |
Описание |
MS_ASYNC |
Выполнять запись асинхронно |
MS_SYNC |
Выполнять запись синхронно |
MS_INVALIDATE |
Обновить другие отражения этого файла так, чтобы они содержали изменения, внесенные этим вызовом |
Функция munmap
освобождает сегмент памяти.
#include
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
#include
#include
#include
#include
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
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);
mapped[43].integer = 243;
sprintf(mapped[43].string, "RECORD-%d", mapped[43].integer);
msync((void *)mapped, NRECORDS*sizeof(record), MS_ASYNC);
munmap((void *)mapped, NRECORDS*sizeof(record));
close(f);
exit(0);
}
В главе 13 вы встретитесь с еще одним средством совместного использования памяти — разделяемой памятью System V.
В этой главе вы увидели, как ОС Linux обеспечивает прямой доступ к файлам и устройствам, как на этих низкоуровневых функциях строятся библиотечные функции, предоставляющие гибкие решения программных проблем. В результате вы смогли написать довольно мощную процедуру просмотра каталога с помощью нескольких строк программного кода.
Вы также узнали об обработке файлов и каталогов достаточно для того, чтобы превратить "сырое" приложение для работы с компакт-дисками, созданное в конце главы 2, в программу на языке С, применяющую более структурированное решение на базе файлов. Но на этом этапе вы не можете расширить функциональные возможности программы, поэтому мы отложим ее переработку до того времени, когда вы научитесь управлять экраном и клавиатурой, которые будут предметами обсуждения следующих двух глав.
Когда вы пишете программу для ОС Linux (или UNIX и UNIX-подобных систем), следует принимать во внимание то, что программа будет выполняться в многозадачной среде или многозадачном окружении. Это означает, что много программ будет выполняться одновременно и совместно использовать ресурсы компьютера, такие как память, дисковое пространство и циклы центрального процессора. Может даже существовать несколько экземпляров одной и той же программы, выполняющихся одновременно. Важно, чтобы эти программы не мешали друг другу, знали о своем окружении и могли действовать надлежащим образом, избегая конфликтов, таких как попытка писать в один и тот же файл одновременно с другой программой.
Читать дальше