Опубликован: 28.06.2006 | Уровень: специалист | Доступ: платный | ВУЗ: Московский государственный технический университет им. Н.Э. Баумана
Лекция 14:

Взаимодействие процессов и потоков

Межпроцессное взаимодействие с использованием проецирования файлов

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

В примере ниже приводится текст двух приложений (first.cpp и second.cpp), которые обмениваются между собой данными через общий объект "проекция файла":

/* FIRST.CPP */
#include <windows.h>
#define DEFAULT_SECURITY  (LPSECURITY_ATTRIBUTES)NULL
int main( void )
{
  HANDLE                hMapping;
  LPVOID                pMapping;
  STARTUPINFO  	        si;
  PROCESS_INFORMATION  	pi;
  int           	*p;
  int           	i;
  memset( &si, 0, sizeof(si) );
  memset( &pi, 0, sizeof(pi) );
  si.cb = sizeof(si);
  hMapping = CreateFileMapping(
    INVALID_HANDLE_VALUE, DEFAULT_SECURITY, PAGE_READWRITE,
    0, 1024, "FileMap-AB-874436342"
  );
  pMapping = MapViewOfFile( hMapping, FILE_MAP_WRITE, 0,0, 0 );
  for (p=(int*)pMapping,i=0; i<256; i++) *p++=i;
  CreateProcess(
    NULL, "second.exe", DEFAULT_SECURITY,
    DEFAULT_SECURITY, FALSE, NORMAL_PRIORITY_CLASS,
    NULL, NULL, &si, &pi);
  CloseHandle( pi.hThread );
  WaitForSingleObject( pi.hProcess, INFINITE );
  CloseHandle( pi.hProcess );
  UnmapViewOfFile( hMapping );
  CloseHandle( hMapping );
  return 0;
}

/* SECOND.CPP */
#include <windows.h>
int main( int ac, char **av )
{
  HANDLE   	 hMapping;
  LPVOID  	 pMapping;
  int     	 *p;
  int     	 i;
  hMapping = OpenFileMapping(
    FILE_MAP_READ, FALSE, "FileMap-AB-874436342"
  );
  pMapping = MapViewOfFile( hMapping, FILE_MAP_READ, 0,0, 0 );
  for ( p = (int*)pMapping, i=0; i<256; i++ )
    if ( *p++ != i ) break;
  if ( i != 256 ) { /* ОШИБКА! */ }
  UnmapViewOfFile( hMapping );
  CloseHandle( hMapping );
  return 0;
}

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

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

Анастасия Булинкова
Анастасия Булинкова
Рабочим названием платформы .NET было
Bogdan Drumov
Bogdan Drumov
Молдова, Республика
Azamat Nurmanbetov
Azamat Nurmanbetov
Киргизия, Bishkek