Частичная передача физической памяти проецируемым файлам
До сих пор мы видели, что система требует передавать проецируемым файлам всю физическую память либо из файла данных на дигке, либо из страничного файла Это значит, что память используется не очень эффективно Давайте вспомним то, что я говорил в разделе "B какой момен! региону передают физическую память" главы 15 Допустим, Вы xoтитe сделать всю таблицу доступной другому процессу Если приме нить для этого механизм проецирования файлов, придется передать физическую па мять целой таблице
CELLDATA CellData[200][256];
Если структура CELLDATA занимает 128 байтов, показанный массив потребует 6 553 600 (200 x 256 x 128) байтов физической памяти Это слишком много — тем бо лее, что в таблице обычно заполняют всего несколько строк
Очевидно, что в данном случае, создав объект "проекцин файла", желательно не передавать ему заранее всю физическую память Функция CreateFtleMapping предус матривает такую возможность, для чего в параметр fdwProtect нужпо передать один из флагов SEC_RESRVE или SEC_COMMlT
Эти флаги имеют смысл, только если Вы создаете объект «проекция файла", ис пользующий физическую память из страничного файла. Флаг SEC_COMMIT заставля ет CreateFileMapping сразу же передать память из страничного файла. (То же самое происходит, если никаких флагов не указано.) Но когда Вы задаете флаг SEC_RESERVE, система не передает физическую память из страничного файла, а просто возвращает описатель объекта «проекция файла". Далее, вызвав MapViewOfFile или MapViewOfFileEx, можно создать представление этого объекта. При этом MapViewOfFile или MapView OfFileEx резервирует регион адресного пространства, не передавая ему физической памяти. Любая попытка обращения по одному из адресов зарезервированного регио на приведёт к нарушению доступа
Таким образом, мы имеем регион зарезервированного адресного пространства и описатель объекта "проекция файла", идентифицирующий этот регион. Другие про цессы могут использовать данный объект для проецирования представления того же региона адресного пространства. Физическая память региону по-прежнему не пере дается, так что, если потоки в других процессах попытаются обратиться по одному из адресов представления в своих регионах, они тоже вызовут нарушение доступа.
А теперь самое интересное. Оказывается, все, что нужно для передачи физической памяти общему (совместно используемому) региону, - вызвать функцию VirtualAlloc:
PVOID VirtualAlloc( PVOID pvAddress, SIZE_T dwSize, DWORD fdwAllocationType, DWORD friwProtect);
Эту функцию мы уже рассматривали (и очень подробно) в главе 15. Вызвать Virtual Alloc для передачи физической памяти представлению региона — то же самое, что вызвать VirtualAlloc для передачи памяти региону, ранее зарезервированному вызовом VirtualAlloc с флагом MEM_RESERVE. Получается, что региону, зарезервированному функциями MapViewOfFile или MapViewOfFileEx, — как и региону, зарезервированно му функцией VirtualAlloc, — тоже можно передавать физическую память порциями, а не всю сразу. И если Вы поступаете именно так, учтите, что все процессы, спроеци ровавшие на этот регион представление одного и того же объекта «проекция файла», теперь тоже получат доступ к страницам физической памяти, переданным региону.
Итак, флаг SEC_RESERVE и функция VirtualAlloc позволяют сделать табличную мат рицу CellData «общедоступной" и эффективнее использовать память.
WINDOWS 98
Обычно VirtualAlloc не срабатывает, если Вы передаете ей адрес памяти, выхо дящий за пределы диапазона от 0x00400000 до 0x7FFFFFFF. Однако при перс даче физической памяти проецируемому файлу, созданному с флагом SEC_RE SERVE, в VirtualAlloc нужно передать адрес, укладывающийся в диапазон от 0x80000000 до 0xBFFFFFFE Только тогда Windows 98 поймет, что физическая память передается региону, зарезервированному под проецируемый файл, и даст благополучно выполнить вызов функции.
WINDOWS 2000
В Windows 2000 функция VirtualFree не годится для воврата физической па мяти, переданной в свос время проецируемому файлу (созданному с флагом SEC_RESERVE). Однако в Windows 98 такого ограничения нет.
Файловая система NTFS 5 поддерживает так называемые разреженные файлы (spar se files). Это потрясяющая новинка. Она позволяет легко создавать и использовать
разреженные проецируемые файлы (sparse memory-mapped files), которым физичес кая память предоставляется не из страничного, а из обычного дискового файла
Вот пример гого, как можно было бы воспользоваться этой новинкой Допустим, Вы хотите создать проецируемый в память файл (MMF) для записи аудиоданных При этом Вы должны записывать речь в виде цифровых аудиоданных в буфер памяти, связанный с дисковым файлом. Самый простой и эффективный способ решить эту задачу — применить разреженный MMF Все дело в том, что Вам заранее не известно, сколько времени будет говорить пользователь, прежде чем щелкнет кнопку Stop. Mo жет, пять минут, а может, пять часов — разница большая! Однако при использовании разреженного MMF это не проблема.