Common Intermediate Language и системное программирование в Microsoft.Net. Макаров А.В - 131 стр.

UptoLike

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