Вы находитесь на странице: 1из 3

Дополнительный материал

Совместный доступ процессов к данным


через проекции файлов

Использование файлов на диске, отображаемых в память


Последовательность действий при создании и использовании проекций файлов в
память для совместного доступа к данным двух и более процессов следующая:
1. Первый процесс создает проекцию файла в память, для чего:
а) открывает заданный файл на диске с помощью функции CreateFile(), которая
возвращает дескриптор этого файла hFile;
б) с помощью функции CreateFileMapping() создает в памяти именованный объект
"проекция файла" с дескриптором hMapFile;
в) отображает проекцию файла на своё адресное пространство с помощью функции
MapViewOfFile(), которая возвращает указатель lpMapData на регион памяти с
отображением проекции файла;
г) доступ к данным в проекции осуществляется через разыменование указателя
*lpMapData;
д) по окончании работы с данными в проекции файла с помощью функции
UnmapViewOfFile() сделать недействительным указатель lpMapData, а затем с
помощью двух вызовов функции CloseHandle() освободить дескрипторы проекции
hMapFile и файла hFile.
2. В других процессах, которые хотят получить доступ к созданной проекции файла,
необходимо:
а) открыть имеющуюся проекцию с помощью функции OpenFileMapping(), задав ей
имя этой проекции. Функция возвращает дескриптор объекта "проекция файла"
hMapFile для этого процесса;
б) отобразить открытую проекцию на адресное пространство процесса с по -
мощью функции MapViewOfFile(). Функция возвращает указатель lpMapData на
отображение этой проекции в память данного процесса;
в) после выполнения указанных выше действий два и более процессов получат
доступ к одному и тому же участку физической памяти, который является проекцией
конкретного файла на диске;
г) по окончании работы с данными в проекции файла эти процессы должны с
помощью функции UnmapViewOfFile() сделать недействительным указатель
lpMapData, а затем, используя функцию CloseHandle(), освободить дескрипторы
проекции hMapFile. При этом все изменения данных в проекции будут сохранены в
файле.
При работе с общим для нескольких процессов объектом "проекция файла"
необходимо учитывать следующее:
- такой объект не будет уничтожен, пока не закроются все его дескрипторы во всех
процессах;
- когда хотя бы один процесс пишет данные в проекцию, а другие читают из неё, то
потребуется использование какого-либо именованного объекта синхронизации (кроме
критической секции) для упорядочения доступа этих процессов к общим данным.
Пример совместного использования проекции файла двумя процессами для чтения и
обработки данных. Исходный файл на диске Numb.dat содержит набор из 5000
случайных целых чисел. Рассмотрим отдельно каждый из процессов:
1. Первый процесс – это приложение App1.exe, которое открывает файл, создает
объект "проекция файла" с именем MyFile, отображает его в свое адресное
пространство, создает второй процесс путем запуска другого приложения App2.exe.
Затем первый процесс читает данные из проекции файла и определяет для этого
набора целых чисел минимальное и максимальное значения.
Файл App1.cpp

// Описание дескрипторов и указателя
HANDLE hFile;
HANDLE hMapFile;
INT *piMapData;
// Открытие исходного файла на диске
hFile=CreateFile("Numb.dat", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
// Создание именованного объекта "проекция файла"
hMapFile=CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, "MyFile");
// Отображение проекции файла на адресное пространство процесса
piMapData = (INT *) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
// Создание дочернего процесса – запуск приложения App2.exe
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
CreateProcess(NULL, "App2.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

// Обработка данных в проекции файла
INT i, iMin, iMax;
iMin = iMax = *piMapData;
for (i=0; i < 5000; i++)
{
if (*(piMapData+i) < iMin)
iMin = *(piMapData+i);
if (*(piMapData+i) > iMax)
iMax = *(piMapData+i);
}

// Завершение работы с проекцией файла
UnmapViewOfFile(piMapData);
CloseHandle(hMapFile);
CloseHandle(hFile);

2. Второй процесс – это запущенное из первого процесса приложение App2.exe,
которое открывает созданную проекцию файла, отображает ее в свое адресное
пространство. Затем второй процесс читает данные из проекции файла и определяет
для этого набора целых чисел среднее значения и среднеквадратическое отклонение.
Файл App2.cpp

// Описание дескрипторов и указателя
HANDLE hFile;
HANDLE hMapFile;
INT *piMapData;
// Открытие именованного объекта "проекция файла"
hMapFile=OpenFileMapping(FILE_MAP_READ, FALSE, "MyFile");
// Отображение проекции файла на адресное пространство процесса
piMapData = (INT *) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);

// Обработка данных в проекции файла
INT i;
FLOAT nAver, nAvSqDev;
for (i=0, nAver=0; i < 5000; i++)
nAver += *(piMapData+i);
nAver /= 5000;
for (i=0, nAvSqDev=0; i < 5000; i++)
nAvSqDev += pow(*(piMapData+i) – nAver, 2);
nAvSqDev /= 5000;

// Завершение работы с проекцией файла
UnmapViewOfFile(piMapData);
CloseHandle(hMapFile);

В результате запуска первого приложения App1.exe и последующего запуска в нем


другого приложения App2.exe, оба созданных процесса получат доступ к данным из
файла Numb.dat, отображенным в память в виде проекции файла.