Составители:
Рубрика:
Важно отметить, что если разные процессы откроют один и тот же
файл, а затем каждый создаст свой собственный объект «проекция файла»,
то система не будет гарантировать когерентности данных в проекциях; коге-
рентность обеспечивается только в рамках одного объекта «проекция фай-
ла». В некоторых случаях можно воспользоваться функцией FlushViewOfFile
для явного сброса данных из оперативной памяти в файл, что, однако, еще
не гарантирует автоматического обновления данных в других проекциях.
Именно механизм проецирования файлов является базовым средст-
вом для передачи данных между адресными пространствами процессов.
Он является основой для построения многих других средств межпроцесс-
ного взаимодействия. Так, например, обмен оконными сообщениями (ес-
ли в сообщении содержится указатель на данные) между разными процес-
сами приводит к тому, что система создает внутренний объект «проекция»,
помещает данные в него, проецирует на второй процесс и посылает сооб-
щение получателю с указателем на проекцию в процессе-получателе.
7.2.2.4. Межпроцессное взаимодействие с использованием общих секций
Еще одна разновидность работы с разделяемыми данными посредст-
вом проецирования файлов связана с объявлением специальных разделя-
емых сегментов в приложении – такие сегменты будут общими для всех
копий этого приложения. В своей основе такой способ является частным
случаем проецирования – с той оговоркой, что проецируется исполняе-
мый файл (или разделяемая библиотека) и управление проекциями осу-
ществляется декларативным способом.
В Microsoft Visual C++ для объявления разделяемого сегмента и по-
мещаемых в него данных используются директивы #pragma и __declspec,
как показано в примере ниже:
/* FSEC.CPP */
#include <windows.h>
#define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL
#pragma section(“SHRD_DATA”,read,write,shared)
__declspec(allocate(“SHRD_DATA”)) int shared[ 256 ];
int main( int ac, char **av )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
int i;
memset( &si, 0, sizeof(si) );
memset( &pi, 0, sizeof(pi) );
Разработка параллельных приложений для ОС Windows
249
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 );
CreateProcess(
NULL, “second.exe”, DEFAULT_SECURITY,
DEFAULT_SECURITY, FALSE, NORMAL_PRIORITY_CLASS,
NULL, NULL, &si, &pi);
CloseHandle( pi.hThread );
for (p=(int*)pMapping,i=0; i<256; i++) *p++=i;
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;
}
248
CIL и системное программирование в Microsoft .NET
248 CIL и системное программирование в Microsoft .NET Разработка параллельных приложений для ОС Windows 249 int *p; Важно отметить, что если разные процессы откроют один и тот же int i; файл, а затем каждый создаст свой собственный объект «проекция файла», memset( &si, 0, sizeof(si) ); то система не будет гарантировать когерентности данных в проекциях; коге- memset( &pi, 0, sizeof(pi) ); рентность обеспечивается только в рамках одного объекта «проекция фай- si.cb = sizeof(si); ла». В некоторых случаях можно воспользоваться функцией FlushViewOfFile hMapping = CreateFileMapping( для явного сброса данных из оперативной памяти в файл, что, однако, еще INVALID_HANDLE_VALUE, DEFAULT_SECURITY, PAGE_READWRITE, не гарантирует автоматического обновления данных в других проекциях. 0, 1024, “FileMap-AB-874436342” Именно механизм проецирования файлов является базовым средст- ); вом для передачи данных между адресными пространствами процессов. pMapping = MapViewOfFile( hMapping, FILE_MAP_WRITE, 0,0, 0 ); Он является основой для построения многих других средств межпроцесс- CreateProcess( ного взаимодействия. Так, например, обмен оконными сообщениями (ес- NULL, “second.exe”, DEFAULT_SECURITY, ли в сообщении содержится указатель на данные) между разными процес- DEFAULT_SECURITY, FALSE, NORMAL_PRIORITY_CLASS, сами приводит к тому, что система создает внутренний объект «проекция», NULL, NULL, &si, &pi); помещает данные в него, проецирует на второй процесс и посылает сооб- CloseHandle( pi.hThread ); щение получателю с указателем на проекцию в процессе-получателе. for (p=(int*)pMapping,i=0; i<256; i++) *p++=i; WaitForSingleObject( pi.hProcess, INFINITE ); 7.2.2.4. Межпроцессное взаимодействие с использованием общих секций CloseHandle( pi.hProcess ); Еще одна разновидность работы с разделяемыми данными посредст- UnmapViewOfFile( hMapping ); вом проецирования файлов связана с объявлением специальных разделя- CloseHandle( hMapping ); емых сегментов в приложении – такие сегменты будут общими для всех return 0; копий этого приложения. В своей основе такой способ является частным } случаем проецирования – с той оговоркой, что проецируется исполняе- мый файл (или разделяемая библиотека) и управление проекциями осу- /* SECOND.CPP */ ществляется декларативным способом. #includeВ Microsoft Visual C++ для объявления разделяемого сегмента и по- int main( int ac, char **av ) мещаемых в него данных используются директивы #pragma и __declspec, { как показано в примере ниже: HANDLE hMapping; LPVOID pMapping; /* FSEC.CPP */ int *p; #include int i; #define DEFAULT_SECURITY (LPSECURITY_ATTRIBUTES)NULL hMapping = OpenFileMapping( FILE_MAP_READ, FALSE, “FileMap-AB-874436342” #pragma section(“SHRD_DATA”,read,write,shared) ); __declspec(allocate(“SHRD_DATA”)) int shared[ 256 ]; pMapping = MapViewOfFile( hMapping, FILE_MAP_READ, 0,0, 0 ); for ( p = (int*)pMapping, i=0; i<256; i++ ) int main( int ac, char **av ) if ( *p++ != i ) break; { if ( i != 256 ) { /* ОШИБКА! */ } STARTUPINFO si; UnmapViewOfFile( hMapping ); PROCESS_INFORMATION pi; CloseHandle( hMapping ); int i; return 0; memset( &si, 0, sizeof(si) ); } memset( &pi, 0, sizeof(pi) );
Страницы
- « первая
- ‹ предыдущая
- …
- 129
- 130
- 131
- 132
- 133
- …
- следующая ›
- последняя »