пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

Архитектура памяти в OC Windows. Механизмы управления памятью в приложениях. Проецируемые в память файлы. Этапы работы с проекциями. Пример

Операции с файлами – это то, что рано или поздно приходится делать практически во всех программах, и всегда это вызывает массу проблем.

В Windows многие из этих проблем решаются очень изящно – с помощью проецируемых в память файлов (memory-mapped files).

Как и виртуальная память, проецируемые файлы позволяют резервировать регион адресного пространства и передавать ему физическую память.

Различие между этими механизмами состоит в том, что в последнем случае физическая память не выделяется из страничного файла, а берется из файла, уже находящегося на диске.

Как только файл спроецирован в память, к нему можно обращаться так, будто он целиком в нее загружен.

Проецируемые файлы применяются для:

загрузки и выполнения EXE- и DLL-файлов. Это позволяет существенно экономить как на размере страничного файла, так и на времени, необходимом для подготовки приложения к выполнению;

доступа к файлу данных, размещенному на диске. Это позволяет обойтись без операций файлового ввода-вывода и буферизации его содержимого;

разделения данных между несколькими процессами, выполняемыми на одной машине (в Windows есть и другие методы для совместного доступа разных процессов к одним данным — но все они так или иначе реализованы на основе проецируемых в память файлов).

Этап 1: создание или открытие объекта ядра «файл» 

psa – указатель на структуру, содержащую дескриптор защиты (по умолчанию NULL)

dwCreationDisposition – определяет режим работы функции CreateFile. Может принимать следующие значения:

Значение

Описание

CREATE_NEW

Создает новый файл. Если файл с таким именем

существует, функция даст ошибку.

CREATE_ALWAYS

Создает новый файл независимо от того,

существует ли файл с таким же именем.

OPEN_EXISTING  

Открывает существующий файл. Если файла нет -

ошибка.

OPEN_ ALWAYS

Открывает существующий файл. Если файла нет -

создает новый.

TRUNCATE_ EXISTING

Открывает существующий файл и обрезает его

длину до 0.

dwFlagsAndAttributes – атрибуты файлов и флаги устройств. Используйте значение FILE_ATTRIBUTE_NORMAL

hTemplateFile – используйте значение NULL.

Этап 2: создание объекта ядра «проекция файла» 

Вызвав CreateFile, Вы указали операционной системе, где находится физическая память для проекции файла на жестком диске в сети, на CD-ROM или в другом месте. Теперь сообщите системе, какой обьем физической памяти нужен проекции файла Для этого вызовите функцию CreateFileMapping:

HANDLE CreateFileMapping( HANDLE hFile,

PSECURITY_ATTRIBUTES psa,

DWORD fdwProtect,

DWOPD dwMaximumSizeHigh,

DWORD dwMaximumSizeLow,

PCSTR pszName);

Функция создает объекта ядра "проекция файла" и возвращает его описатель.

Если это не удалось, возвращает NULL. 

hFile – идентифицирует описатель файла, проецируемою на адресное пространство процесса. Этот описатель Вы получили после вызова CreateFile.

Параметр psa – указатель на структуру SECURITY_ATTRIBUTES, которая относится к объекту ядра "проекция файла", для установки защиты по умолчанию ему присваивается NULL.

В fdwProteсt надо указать желательные атрибуты защиты. Обычно используется один из перечисленных в следующей таблице:

Атрибут защиты

Описание

PAGE_READONLY

Отобразив объект «проекция файла» на адресное пространство, можно считывать данные из файла. При этом Вы должны были передать в CreateFile флаг GENERIC_READ.

PAGE_READWRITE

Отобразив объект «проекция файла» на адресное пространство, можно считывать данные из файла и записывать их. При этом Вы должны были передать в CreateFile комбинацию флагов GENERIC_READ | GENERIC_WRITE.

PAGE_WRITECOPY

Отобразив объект "проекция файла" на адресное пространство, можно считывать данные из файла и записывать их. Запись приведет к созданию закрытой копии страницы. При этом Вы должны были передать в CreateFile либо GENERIC_READ, либо GENERIC_READ | GENERIC_WRITE

dwMaximumSizeHigh, dwMaximumSizeLow – размер доступной физической памяти, иначе говоря, максимальный размер файла, проецируемого на адресное пространство.

Win32 позволяет работать с файлами, размеры которых выражается 64-х разрядным числом (до 18 экзабайтов ).

Поэтому dwMaximumSizeLow отражает младшие 32 бита, dwMaximumSizeHigh – старшие.

Для отражения текущего состояния файла укажите в обоих параметрах 0. В этом случае Вы не сможете дописывать в файл.

pszName – имя объекта. Обычно NULL.

Этап 3: проецирование файловых данных на адресное пространство процесса 

Когда объект "проекция файла“ создан, нужно, чтобы система, зарезервировав регион адресного пространства под данные файла, передала их как физическую память, отображенную на регион. Это делает функция MapViewOfFile:

PVOID MapViewOfFile(HANDLE hFileMappingObject,

DWORD dwDesiredAccess,

DWORD dwFileOffsetHigh,

DWORD dwFileOffsetLow,

SIZE_T dwNumberOfBytesToMap);

Параметр hFileMappingObject идентифицирует описатель объекта "проекция файла", возвращаемый предшествующим вызовом либо CreateFileMapping, либо OpenFileMapping.

Параметр dwDesiredAccess идентифицирует вид доступа к данным. Придется опять указывать, как именно мы хотим обращаться к файловым данным. Можно задать одно из четырех значений, описанных в следующей таблице:

Значение

Описание

FILE_MAP_WRITE

Файловые данные можно считывать и записывать.

Вы должны были передать функции CreateFileMapping атрибут PAGE_READWRITE

FILE MAP_READ

Файловые данные можно только считывать.

 Вы должны были вызвать CreateFileMapping с любым из следующих атрибутов PAGE_READONLY, PAGE_READWRITE или PAGE_WRITECOPY

FILE_MAP_ALL_ACCESS

То же, что и FILE_MAP_WRITE

FILE_MAP_COPY

Файловые данные можно считывать и записывать, но запись приводит к созданию закрытой копии страницы.

Вы должны были вызвать CrealeFileMapping с любым из следующих атрибутов PAGE_READONIY, PAGE_READWRITE или РАСЕ_WRITECOPY

Проецируя на адресное пространство процесса представление файла, нужно сделать две вещи:

Во-первых, нужно сообщить системе, какой байт файла данных считать в представлении первым Для этого предназначены параметры dwFileOffsetHigh и dwFile OffsetLow. Поскольку Windows поддерживает файлы длиной до 16 экзабайтов, приходится определять смещение в файле как 64 разрядное число. Старшие 32 бита передаются в параметре dwFileOffsetHigh, а младшие 32 бита — в параметре dwFileOffsetLow. Смещение в файле должно быть кратно гранулярности выделения памяти в данной системе.

Во-вторых, нужно указать размер представления, т.e. сколько байтов файла данных должно быть спроецировано на адресное пространство. Размер указывается в параметре dwNumberOfBytesToMap. Если этот параметр равен 0, система попытается спроецировать представление, начиная с указанного смещения и до конца файла.

Этап 4: отключение файла данных от адресного пространства процесса 

Когда необходимость в данных файла, спроецированного на адресное пространство, отпадает, необходимо освободить регион

BOOL UnmapViewOfFile(PVOID pvBaseAddress);

lpBaseAddress - базовый адрес региона.

Так как повторный вызов MapViewOfFile приводит к резервированию нового региона, но не освобождению старого, необходимо вызывать UnMapViewOfFile после каждого вызова MapViewOfFile.

Для повышения производительности ОС буферизует страницы данных и не сохраняет их немедленно в дисковом образе файла. При необходимости можно заставить ОС записать все измененные данные на диск

BOOL FlushViewOfFile(PVOID pvAddress, SIZE_T dwNumberOfBytesToFlush);

lpBaseAddress – базовый адрес региона.

dwNumberOfBytesToFlush – кол-во байтов, переписываемых на диск.

Этапы 5 и 6: закрытие объектов «проекция файла» и «файл» 

Закончив работу с любым открытым объектом ядра, нужно его закрыть, иначе в процессе начнется утечка ресурсов.

По завершении процесса система автоматически закроет объекты, оставленные открытыми.

Но, если процесс по работает еще какое-то время, может накопиться слишком много незакрытых описателей.

Для закрытия объектов «проекция файла» и «файл» дважды вызовите функцию CloseHandle:

HANDLE hFile = CreateFile(...);

HANDLE hFileMapping = CreateFileMapping(hFile,...);

PVOID pvFilfi = MapViewOfFile(hFileMapping, );

// работаем с файлом, спроецированным в память

UnmapViewOfFile(pvFile);

CloseHandle(hFileMapping);

CloseHandle(hFile); 


26.12.2015; 23:13
хиты: 0
рейтинг:0
Точные науки
информатика
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь