Составители:
Рубрика:
Важно отметить, что если разные процессы откроют один и тот же
файл, а затем каждый создаст свой собственный объект «проекция файла»,
то система не будет гарантировать когерентности данных в проекциях; коге-
рентность обеспечивается только в рамках одного объекта «проекция фай-
ла». В некоторых случаях можно воспользоваться функцией 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
- …
- следующая ›
- последняя »
