Читайте также:
|
|
Для закрепления материала, изложенного в предыдущем разделе, рассмотрим пример программы.
/* Программа 5-1.с для иллюстрации работы с
memory mapped файлом */
int main(void)
{
int fd; /* Файловый дескриптор для файла, в
котором будет храниться наша информация*/
size_t length; /* Длина отображаемой части файла */
int i;
/* Ниже следует описание типа структуры, которым мы забьем
файл, и двух указателей на подобный тип. Указатель ptr
будет использоваться в качестве начального адреса
выделенной области памяти, а указатель tmpptr – для
перемещения внутри этой области. */
struct A {
double f;
double f2;
} *ptr, tmpptr;
/* Открываем файл или сначала создаем его (если
такого файла не было). Права доступа к файлу при создании
определяем как read-write для всех категорий пользователей
(0666). Из-за ошибки в Linux мы будем вынуждены ниже в
системном вызове mmap() разрешить в отображении файла и
чтение, и запись, хотя реально нам нужна только запись.
Поэтому и при открытии файла мы вынуждены задавать O_RDWR. */
fd = open("mapped.dat", O_RDWR | O_CREAT, 0666);
if(fd == -1){
/* Если файл открыть не удалось, выдаем
сообщение об ошибке и завершаем работу */
printf("File open failed!\n");
exit(1);
}
/* Вычисляем будущую длину файла (мы собираемся записать
в него 100000 структур) */
length = 100000*sizeof(struct A);
/* Вновь созданный файл имеет длину 0. Если мы его
отобразим в память с такой длиной, то любая попытка
записи в выделенную память приведет к ошибке. Увеличиваем
длину файла с помощью вызова ftruncate(). */
ftruncate(fd,length);
/* Отображаем файл в память. Разрешенные операции над
отображением указываем как PROT_WRITE | PROT_READ по
уже названным причинам. Значение флагов ставим в
MAP_SHARED, так как мы хотим с охранить информацию,
которую занесем в отображение, на диске. Файл
отображаем с его начала (offset = 0) и до конца
(length = длине файла). */
ptr = (struct A)mmap(NULL, length, PROT_WRITE |
PROT_READ, MAP_SHARED, fd, 0);
/* Файловый дескриптор нам более не нужен, и мы его
закрываем */
close(fd);
if(ptr == MAP_FAILED){
/* Если отобразить файл не удалось, сообщаем об
ошибке и завершаем работу */
printf("Mapping failed!\n");
exit(2);
}
/* В цикле заполняем образ файла числами от 1 до 100000
и их квадратами. Для перемещения по области памяти
используем указатель tmpptr, так как указатель ptr на
начало образа файла нам понадобится для прекращения
иотображения вызовом munmap(). */
tmpptr = ptr;
for(i = 1; i <=100000; i++){
tmpptr->f = i;
tmpptr->f2 = tmpptr->f*tmpptr->f;
tmpptr++;
}
/* Прекращаем отображать файл в память, записываем
содержимое отображения на диск и освобождаем память. */
munmap((void *)ptr, length);
return 0;
}
Листинг 5.1. Программа 5-1.с для иллюстрации работы с memory mapped файлом.
Эта программа создает файл, отображает его в адресное пространство процесса и заносит в него информацию с помощью обычных операций языка С.
Обратите внимание на необходимость увеличения размера файла перед его отображением. Созданный файл имеет нулевой размер, и если его с этим размером отобразить в память, то мы сможем записать в него или прочитать из него не более 0 байт, т.е. ничего. Для увеличения размера файла использован системный вызов ftruncate(), хотя это можно было бы сделать и любым другим способом.
Поскольку информацию мы желаем сохранить на диске, при отображении использовано значение флагов MAP_SHARED. Откомпилируйте эту программу и запустите ее.
Дата добавления: 2014-12-19; просмотров: 148 | Поможем написать вашу работу | Нарушение авторских прав |