Студопедия

КАТЕГОРИИ:

АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника


Отображение файлов в виртуальное адресное пространство. Разделяемая память.




В OC Unix процесс имеет возможность отобразить участки файла в собственное адресное пространство. Далее с данными в файле можно работать как с обычными переменными. Фактически этот механизм является альтернативой механизму read/write. Отображение осуществляется с помощью mmap:

#include <sys/types.h>

#include <sys/mman.h>

Caddr_t //соответствует void* - безтиповый указатель.

Caddr_t mmap(caddr_t addr,int len,int prot,int flags,int fd,int offset);

Этот вызов задает отображение len байт в файл с дискриптором fd начиная с позиции offset со стартовым адресом addr. Параметр prot определяет права доступа к области памяти, которые должны соответствовать правам доступа к файлу. Права доступа к fd указываются предварительно в open. До использования mmap файл fd должен быть открыт.

Prot_READ – только для чтения

Prot_WRITE – только для записи

Prot_EXEC – доступен для исполнения

Prot_NONE – область недоступна

С помощью логического ИЛИ (|) можно объединять условия. Наличие EXEC говорит о возможности передачи управления в область отражения. Такой подход ипользуется при загрузки динамических библиотек, когда библиотека отображается в адресное пространство процесса. Параметр flags задает дополнительные механизмы отображения:

MAP_SHARED – область памяти может совместно использоваться несколькими процессами

MAP_PRIVATE – используется только вызывающим процессом

MAP_FIXED – требует выделения памяти точно начиная с addr.

Можно через логическое ИЛИ добавлять к флагам опции. Например MAP_ANONYMOUS. Эта опция позволяет создать просто область памяти, без файла fd, и offset игнорируется в этом случае. Если память выделена, то mmap с параметром ANONYMOUS отличается от обычной тем, что при копировании процесса вызовом fork(), эта память не копируется, а становится доступной для обоих процессов. Значение параметра addr обычно задается равным NULL. Тогда ОС сама выбирает свободную область виртуального адресного пространства. В случае ошибки mmap возвращает значение (-1), преобразованное в void*, т.е. будет иметь вид MAP_FAILED.

Отображение автоматически снимается при завершении процесса. Процесс может явно снять отображение с помощью системного вызова int munmap(void* addr,int len);

Закрытие файла не приведет к снятию отображения. Снятие отображения не влияет немедленно на файл. Обновление файла производится ядром согласно механизму управления виртуальной памятью. msync() – позволяет синхронизировать обновление страниц в памяти с вторичной памятью. При выполнении mmap OC округляет len до следующей страницы виртуальной памяти. Например размер файла 96 байт, а размер страницы 4096 байт, то 96 байт займут данные файла, а 4к байт будет заполнено нулями, но процесс сможет модифицировать эти 4кб. На содержимом файла это не отбразится. Процесс не может изменить размер файла.

Пример 1: #include <sys/types.h>

#include <sys/mman.h>

main()

{int fd; char*ptr;

fd=Open(“f1.at”,O_RDWR);

if (fd==-1){perror(“ошибка open”);exit(1);}

ptr=(char*) mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);

if (ptr==MAP_FAILED){perror(“ошибка mmap”);exit(2);}

……….

После успешного вызова mmap выражение ptr[25], будет равно значению 26ого байта из файла. Операция ptr[26]=”a” занесет в 26ой байт символ “a”.

Пример 2: #include <sys/types.h>

#include <sys/mman.h>

main()

{int* ptr;

ptr=(char*)mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,0,0);

if (ptr== FAILED){perror(“ошибка mmap”);exit(1);}

if fork()==0) then {//дочерний процесс//}

else {//родительский процесс//}

В примере родительский и дочерний процессы имеют доступ к массиву целых чисел размером по 4 байта. Массив доступен через ptr.

Пример 3: Упрощенная версия копирования файлов – cp.

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/mman.h>

#include <unistd.h>

#include <fcntl.h>

main(int argC,char* argV[])

{int fd1,fd2;caddr_t addr1(исходный),addr2(целевой);

struct stat filestat;//тип stat для структуры filestat содержит метаданные из файлового дискриптора.

fd1=open(argV[1],O_RDONLY);

fd2=open(argV[2],O_WRONLY);

fstat(fd1,&filestat);//определяем размер исходного файла

lseek(fd2,filestat.st_size-1,SEEK_SET);//делаем размер целевого файла равным исходному

write(fd2,””,1);

addr1=mmap(NULL,filestat.st_size,PROT_READ|PROT_WRITE,fd1,0);

addr2=mmap(NULL,filestat.st_size,PROT_READ|PROT_WRITE,fd2,0);

memcpy(addr2,addr1,filestat.st_size);

exit(0);}

 

 


Поделиться:

Дата добавления: 2015-01-14; просмотров: 84; Мы поможем в написании вашей работы!; Нарушение авторских прав





lektsii.com - Лекции.Ком - 2014-2024 год. (0.005 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав
Главная страница Случайная страница Контакты