Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Zanyatie_5.docx
Скачиваний:
2
Добавлен:
11.07.2019
Размер:
92.5 Кб
Скачать

Анализ, компиляция и прогон программы для создания memory mapped файла и записи его содержимого

Для закрепления материала, изложенного в предыдущем разделе, рассмотрим пример программы.

/* Программа 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. Откомпилируйте эту программу и запустите ее.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]