Win32-Interprocess communication (shared memory) instance Analysis _c language

Source: Internet
Author: User

I. Overview

In many cases, in Windows programs, there is often a need to exchange data and communicate data between processes. The WIN32 API provides a number of functions that allow us to communicate between processes in a convenient and efficient process, through which we can control the exchange of data between different processes.

interprocess communication (i.e., same-machine communication) and data exchange have many ways: messages, shared memory, Anonymous (named) pipes, postal slots, Windows Sockets and many other technologies. Shared memory can be defined as a memory that is visible to more than one process or a virtual address space that exists in multiple processes. For example, if two processes use the same DLL, only the code page of the DLL is loaded into memory once, and all other processes that map the DLL can share the code pages; by using the message mechanism, IPC has some disadvantages, such as small amount of exchanged data and less information to carry, but because of its convenience, The application is flexible and widely used in internal process communication system without large and frequent data exchange.

Realization of shared memory between same machine processes

Using memory-mapped files to implement WIN32 communication: The mechanism of memory-mapped files in Windows provides a way for us to efficiently manipulate files, allowing us to preserve a memory area in the WIN32 process and map the target files on the hard disk or page file to this virtual memory. Note: synchronization between processes must be considered in the implementation of the program.

The following steps are implemented:

1. Call the memory-mapped API function in the server-side process createfilemapping Create a shared memory with a name identity;

The function CreateFileMapping prototype is as follows:

HANDLE createfilemapping (
HANDLE hfile,//mapping file handle, set to 0xFFFFFFFF (i.e.: INVALID_HANDLE_VALUE) to create an object
shared between processes Lpsecurity_attributes lpfilemappingattributes,//Security Properties
DWORD Flprotect,//Protection mode
DWORD Dwmaximumsizehigh,// The size of the object
DWORD dwmaximumsizelow, 
LPCTSTR lpname//mapping filename, that is, the name of the shared memory
;

Similar to virtual memory, the protection mode parameter can be either Page_readonly or Page_readwrite. If multiple processes have write access to the same shared memory, you must maintain synchronization between each other. The mapping file can also specify the PAGE_WRITECOPY flag to ensure that its original data is not compromised, while allowing other processes to manipulate the copy of the data as necessary.

For example, create a well-known mapping file named "Zzj" with a length of 4096 bytes:

HANDLE m_hmapfile=createfilemapping (HANDLE) 0xffffffff,null,page_readwrite,0,0x1000, "Zzj");

2. After creating the file mapping object, the server-side process calls the MapViewOfFile function to map to the address space of this process;
Example: Mapping a buffer view

void* M_pbasemapfile=mapviewoffile (m_hmapfile,file_map_read| file_map_write,0,0,0);

3. The client process accesses the shared memory object and needs to call the OpenFileMapping function through the memory object name to get the handle of the shared memory object

HANDLE m_hmapfile =openfilemapping (file_map_write,false, "Zzj"); 

4. If the client process obtains a successful handle to the shared memory object, call the MapViewOfFile function to map the object view. Users can use this object view for data read and write operations to achieve the purpose of data communication.
Example: Mapping a buffer view

void* M_pbasemapfile=mapviewoffile (m_hmapfile,file_map_read| file_map_write,0,0,0);

5. When the user process ends using shared memory, call the UnmapViewOfFile function to cancel the view in its address space:

if (m_pbasemapfile) 
{ 
  unmapviewoffile (m_pbasemapfile); 
  Sharedmapview=null; 
}

The use of file mapping to achieve shared memory.

Filemapping is used to put a file that exists on a disk into the virtual address space of a process and generate a zone in the virtual address space of the process to "store" the file, which is called file View (stored in the virtual memory of the process), and the system produces a file Mapping Object (stored in physical memory) is used to maintain this mapping relationship so that when multiple processes need to read and write data for that file, their file view actually corresponds to the same file Mapping Object, which saves memory and keeps data synchronized , and achieve the purpose of data sharing.

Of course, when an application writes data to a file, other processes should not read the data being written. This requires some synchronized operation. Look at the specific API below.

Usage of createfilemaping:

HANDLE createfilemapping (///returns the handle to the Filemapping object
HANDLE hfile,//The handle of the file to which the mapping is to be generated
lpsecurity_attributes Lpattributes,//Security attributes (NT and 2000 only)
DWORD Flprotect,//Protect Peugeot
DWORD Dwmaximumsizehigh,//deposit File in high position of DWORD
Mapping object//Size
DWORD dwmaximumsizelow,///the size of the File Mapping object//In the low DWORD
(usually one of these two parameters is 0)
LPCTSTR lpname//file The name of the Mapping object.
);

1) physical file handle

Any physical file handle that you can get, if you need to create a physical file-independent memory map, it's okay to set it to 0xFFFFFFFF (INVALID_HANDLE_VALUE).

If you need to associate with a physical file, make sure that your physical file is created with an access pattern that matches the "protection settings", such as a physical file read-only and a memory map that requires reading and writing. It is recommended that your physical files be created using exclusive means.

If you use Invalid_handle_value, you also need to set the size of the memory space that you want to request, regardless of whether the physical file handle parameter is valid, so that createfilemapping can create a memory space that is independent of the size of the physical file. Even more than the actual file size, if your physical file is valid, and the size parameter is 0, then return to you is a physical file size of the same memory space address range. Return to your file map address space can be copied, integrated or named to get the initial content of 0.

2) Protection settings

is a security setting, but it is generally set to NULL, using the default security configuration. If the restrictions are required under Win2K, this is for those application processes that share the memory file mapping to the entire network and can be considered for limitations.

3 high-level file size

32-bit address space, set to 0.

4) Shared memory name

The name can contain the "global" or "local" prefix in the global or session name space for the primary file mapping. Other parts can contain any character other than (), and you can refer to Kernel Object name spaces.

5) The corresponding error of GetLastError when calling CreateFileMapping

Error_file_invalid If you attempt to create a 0-length file map, you should have this report
Error_invalid_handle If you find your named memory space and existing memory mappings, mutexes, semaphores, and a critical area with the same name, you're in trouble.
Error_already_exists indicates that the memory space name already exists

Use the function createfilemapping to create a handle to the file data you want to share, then use MapViewOfFile to get the shared memory address, and then use the OpenFileMapping function to open the name of the shared file in another process. This enables different processes to share data.

code example: This program includes a client and a server, server-side to create shared memory, the client open shared memory, both through two events mutually exclusive access to shared memory, the implementation of a small function, is the server process from the console read data sent to the client process.

Service side:

#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std; 
  int main () {HANDLE Hmutex = NULL; 
  HANDLE hfilemapping = NULL; 
  LPVOID lpsharememory = NULL; 
  HANDLE hserverwriteover = NULL; 
 
  HANDLE hclientreadover = NULL; 
    Create share memory Hfilemapping = createfilemapping (Invalid_handle_value, NULL, Page_readwrite, 0, 
  1024*1024, L "sharememorytest"); 
    if (NULL = = hfilemapping) {cout << "createfilemapping fail:" << GetLastError () << Endl; 
  Goto Server_share_memory_end; 
    Lpsharememory = MapViewOfFile (hfilemapping, file_map_all_access, 0, 0,//memory start address   0); All memory spaces if (NULL = = lpsharememory) {cout << "MapViewOfFile" << GetLastError () << 
    Endl 
  Goto Server_share_memory_end; 
  } Hmutex = CreateMutex (NULL, FALSE, L "Sm_mutex"); if (NULL = = Hmutex | | Error_already_exists == GetLastError ()) {cout << "CreateMutex" << GetLastError () << Endl; 
  Goto Server_share_memory_end; 
  }//Multiple threads Mutex Access//send Data Hserverwriteover = CreateEvent (NULL, TRUE, FALSE, L "Serverwriteover"); 
  Hclientreadover = CreateEvent (NULL, TRUE, FALSE, L "Clientreadover"); 
    if (NULL = = Hserverwriteover | | 
    NULL = = hclientreadover) {cout << "CreateEvent" << GetLastError () << Endl; 
  Goto Server_share_memory_end; 
  } char p = 0; 
  char* q = (char*) lpsharememory; 
    do {p = GetChar (); 
    if (WaitForSingleObject (Hclientreadover, 5*1000)!= wait_object_0) goto server_share_memory_end; 
    Q[0] = p; if (! ResetEvent (hclientreadover)) goto server_share_memory_end;//Sets the specified event object to a no signal state if (! 
 
SetEvent (hserverwriteover)) goto server_share_memory_end;//Sets the specified event object to a signaled state} while (P!= ' \ n '); Server_share_memory_end://release SHARE MEMORY if (NULL!= HservErwriteover) CloseHandle (hserverwriteover); 
  if (NULL!= hclientreadover) CloseHandle (hclientreadover); 
  if (NULL!= lpsharememory) unmapviewoffile (lpsharememory); 
  if (NULL!= hfilemapping) CloseHandle (hfilemapping); 
  if (NULL!= Hmutex) ReleaseMutex (Hmutex); 
return 0; 

 }

Client:

#include "stdafx.h" #include <Windows.h> #include <iostream> using namespace std; 
  int main () {HANDLE Hmutex = NULL; 
  HANDLE hfilemapping = NULL; 
  LPVOID lpsharememory = NULL; 
  HANDLE hserverwriteover = NULL; 
 
  HANDLE hclientreadover = NULL; 
  Hmutex = OpenMutex (mutex_all_access, FALSE, L "Sm_mutex"); if (NULL = = Hmutex) {if (Error_file_not_found = = GetLastError ()) {cout << OpenMutex fail:fil 
      E not found! "<< Endl; 
    Goto Client_share_memory_end; 
      else {cout << "OpenMutex fail:" << GetLastError () << Endl; 
    Goto Client_share_memory_end; } if (WaitForSingleObject (Hmutex, 5000)!= wait_object_0)//hmutex Once the mutex is in a signaled state, the function returns {DWORD Dwerr = G 
    Etlasterror (); 
  Goto Client_share_memory_end; 
  }//open share Memory hfilemapping = openfilemapping (file_map_all_access, FALSE, L "sharememorytest"); if (NULL = = Hfilemapping) {cout << "openfilemapping" << GetLastError () << Endl; 
  Goto Client_share_memory_end; 
  } lpsharememory = MapViewOfFile (hfilemapping, file_map_all_access, 0, 0, 0); 
    if (NULL = = lpsharememory) {cout << "MapViewOfFile" << GetLastError () << Endl; 
  Goto Client_share_memory_end; 
  }//read and write Data Hserverwriteover = CreateEvent (NULL, TRUE, FALSE, L "Serverwriteover"); 
  Hclientreadover = CreateEvent (NULL, TRUE, FALSE, L "Clientreadover"); 
    if (NULL = = Hserverwriteover | | 
    NULL = = hclientreadover) {cout << "CreateEvent" << GetLastError () << Endl; 
  Goto Client_share_memory_end; 
  } char p = 0; 
  char* q = (char*) lpsharememory; do {if (! 
 
    SetEvent (hclientreadover)) goto client_share_memory_end; if (WaitForSingleObject (Hserverwriteover, INFINITE)!= wait_object_0) Goto CLIENT_share_memory_end; 
    p = q[0]; 
    Putchar (P); if (! 
  ResetEvent (hserverwriteover)) goto client_share_memory_end; 
 
while (P!= ' \ n '); 
  Client_share_memory_end://release SHARE MEMORY if (NULL!= hserverwriteover) CloseHandle (hserverwriteover); 
  if (NULL!= hclientreadover) CloseHandle (hclientreadover); 
  if (NULL!= lpsharememory) unmapviewoffile (lpsharememory); 
  if (NULL!= hfilemapping) CloseHandle (hfilemapping); 
  if (NULL!= Hmutex) ReleaseMutex (Hmutex); 
return 0;
 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.