Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание эффективных приложений для Windows Джеффри Рихтер 2004 (Книга).pdf
Скачиваний:
385
Добавлен:
15.06.2014
Размер:
8.44 Mб
Скачать

Как и все объекты ядра, проекции файлов можно совместно использовать из не скольких процессов тремя методами: наследованием описателей, именованием и дуб лированием описателей. Подробное объяснение этих трех методов см. в главе 3.

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

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

Прекрасно понимая это, Microsoft добавила возможность проецирования файлов непосредственно на физическую память из страничного файла, а не из специально создаваемого дискового файла. Этот способ даже проще стандартного — основанно го на создании дискового файла, проецируемого в память. Во-первых, не надо вызы вать CreateFile, так как создавать или открывать специальный файл не требуется Вы просто вызываете, как обычно, CreateFileMapping и передаете INVALID_HANDLE_VALUE в параметре hFite. Тем самым Вы указываете системе, что создавать объект «проекция файла», физическая память которого находится на диске, не надо; вместо этого сле дует выделить физическую память из страничного файла. Объем выделяемой памяти определяется параметрами dwMaximumStzeHigh и dwMaximumSizeLow.

Создав объект «проекция файла" и спроецировав его представление на адресное пространство своего процесса, его можно использовать так же, как и любой другой регион памяти. Если Вы хотите, чтобы данные стали доступны другим процессам, вызовите CreateFileMapping и передайте в параметре pszName строку с нулевым сим волом в конце. Тогда посторонние процессы — если им понадобится сюда доступ — смогут вызвать

CreateFileMapping или OpenFileMapping и передать ей то же имя.

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

NOTE:

Есть одна интересная ловушка, в которую может попасть неискушенный про граммист. Попробуйте догадаться, что неверно в этом фрагменте кода:

HANDLE hFile = CreateFile(...);

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

if (hMap == NULL)

return(GetLasttrror());

...

Если вызов CreateFile не удастся, она вернет INVALID_HANDLE_VALUE. Но программист, написавший этот код, не дополнил его проверкой на успешное создание файла. Поэтому, когда в дальнейшем код обращается к функции Create FileMapping, в параметре hFile ей передается INVALID_HANDLE_VALUE, что зас тавляет систему создать объект "проекция файла» из ресурсов страничного файла, а не из дискового файла,

как предполагалось в программе. Весь после дующий код, который используег проецируемый файл, будет работать правиль но. Но при уничтожении объекта «проекция файла" все данные, записанные в спроецированную память (страничный файл), пропадут. И разработчик будет долго чесать затылок, пытаясь понять, в чем дело!

Программа-пример MMFShare

Эта программа, «17 MMFShare.exe» (см. листинг на рис. 17-3), демонстрирует, как про исходит обмен данными между двумя и более процессами с помощью файлов, про ецируемых в память. Файлы исходного кода и ресурсов этой программы находятся в каталоге 17-MMFShare на компакт-диске, прилагаемом к книге.

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

Чтобы переслать данные из одной копии MMFShare в другую, наберите какой нибудь текст в поле Data. Затем щелкните кнопку Create Mapping Of Data. Программа вызовет функцию CreateFileMapping, чтобы создать объект «проекция файла» разме ром 4 Кб и присвоить ему имя MMFSharedData (ресурсы выделяются объекту из стра

ничного файла) Увидев, что объект с таким именем уже существует, программа вы даст сообщение, что не может создать объект. Л если такого объекта нет, программа создаст объект, спроецирует представление файла на адресное пространство процесса и скопирует данные из поля Data в проецируемый файл.

Далее MMFShare прекратит проецировать представление файла, отключит кнопку Create Mapping Of Data и активизирует кнопку Close Mapping Of Data. На этот момент проецируемый в память файл с именем MMFSharedData будет просто «сидеть» где-то в системе. Никакие процессы пока не проецируют представление на данные, содер жащиеся в файле.

Если Вы теперь перейдете в другую копию MMFShare и щелкнете там кнопку Open Mapping And Get Data, программа попытается найти объект «проекция файла" с име нем MMFSharedData через функцию OpenFileMapping, Если ей не удастся найли объект с таким именем, программа выдаст соответствующее сообщение В ином случае она спроецирует представление объекта на адресное пространство своего процесса и скопирует данные из проецируемого файла в поле Data. Вот и все! Вы переслали дан ные из одного процесса в другой

Кнопка Close Mapping OfData служит для закрытия объекта «проекция файла», что высвобождает физическую память, занимаемую им в страничном файле. Если же объект «проекция файла» не существует, никакой другой экземпляр программы MMFShare не сможет открыть зтот объект и получить от него данные Кроме того, если один экземпляр