Shared memory implements Interprocess communication Collection _ Newsletter

Source: Internet
Author: User

A process is usually defined as an instance of a running program that consists of two parts: one is the kernel object that the operating system uses to manage processes. The kernel object is also where the system is used to store statistics about the process. The other is the address space, which contains the code and data for all executable modules or DLL modules. It also contains dynamically allocated space. such as the thread stack and heap allocation space. Each process is given its own virtual address space, and when a thread in the process is running, the thread can access the memory of the process that belongs to it. Memory belonging to other processes is hidden and cannot be accessed by a running thread.
Communication between two processes includes: Clipboard clipboard, window Wm_copydata message, Shared memory mode, message pipeline, mail slot, Windows socket, remote procedure call RPC, serial/parallel communication, com/dcom.
This article describes shared memory methods for communication between implementation processes. Filemapping is used to put a file that exists on a disk into the virtual address space of a process and create a zone in the virtual address space of the process to "store" the file, which is called File View, and the system produces a file Mapping Object (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 to achieve the purpose of data sharing. The use of shared memory in the processing of large amounts of data in the rapid exchange of data shows good performance, in terms of data reliability and so much higher than the way to send wm_copydata messages (Wm_copydata message for small amount of data exchange between processes). This kind of large capacity and high speed data sharing processing method has a good effect in designing high speed digital communication software.


1, shared memory ways to implement communication between processes:
One process process: the CreateFileMapping () function creates a memory-mapped file object, and if the creation succeeds, the file is MapViewOfFile by the () function The view of the mapped object is mapped into the address space, and the first address of this mapping view is obtained. Access address for data read and write. When the data transfer is over and the program is exiting, the mapped memory file needs to be mapped to the object view uninstall and the release of the resource. This part of the work is done primarily by functions such as UnmapViewOfFile () and CloseHandle ().
Another process process: the openfilemapping () function opens a named file mapping object that, if executed successfully, continues using the MapViewOfFile () function to map the view of this file-mapped object to the receiving application's address space and get its first site. Access address for data read and write. When the data transfer is over and the program is exiting, the mapped memory file needs to be mapped to the object view uninstall and the release of the resource. This part of the work is done primarily by functions such as UnmapViewOfFile () and CloseHandle ().
about how to notify another process to read after data processing, there are two ways: first, message notification; the second is to define a data structure header, set the flag bit, thread detection flag bit, according to the flag bit state to determine whether the processing completed, if the processing completed through the event to wake another event to process

HANDLE CreateFileMapping (
HANDLE hfile,//physical file handle
Lpsecurity_attributes lpattributes,//Security settings
DWORD Flprotect,//Protection settings
DWORD Dwmaximumsizehigh,//High file size
DWORD Dwmaximumsizelow,//low file size
LPCTSTR lpname//Shared memory name
);

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
Brethren, I think our machines are now 32-bit, it is impossible to get more than 32-bit process can address the private 32-bit space, usually set 0 bar, I do not want to try to set it more than 0 of the situation.
4 Low File size
This can still be set, but in order for other shared users to know about the file map you are applying for, when I use it, I add a structured description to the head of the address space I get, record the size of the memory map, name, etc., so that the actual application space is larger than the input of the header information structure size, I think such a BSTR approach should be more reasonable.

5) Shared Memory name
This is my test today when the bane of the wall, because in order to the memory of mutually exclusive access, I set a mutex handle, and the name I choose and name shared memory, under the same name, because they use the common namespace caused the error, hehe.

7) 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

8) related services or the naming of the platform reservation
Terminal Services:
The name can contain "global" or "local" prefixes in the global or session-name space for the primary file mapping. Other parts can contain any characters other than () and can refer to the Kernel Object Name spaces.

Windows later or:
If Terminal Services does not have the special meaning of running "Global" and "local" prefixes, it is ignored
LPVoid
WinAPI
MapViewOfFile (
__in HANDLE Hfilemappingobject,
__in DWORD dwDesiredAccess,
__in DWORD Dwfileoffsethigh,
__in DWORD Dwfileoffsetlow,
__in size_t Dwnumberofbytestomap
);

Hfilemappingobject is a shared file object.
dwDesiredAccess is a file share property.
Dwfileoffsethigh is the offset address of the file share.
Dwfileoffsetlow is the offset address of the file share.
Dwnumberofbytestomap is the shared data length.


HANDLE WINAPI OpenFileMapping (
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in LPCTSTR lpname
);
dwDesiredAccess Long, a constant with a prefix of file_map_xxx. A description of the dwdesiredaccess parameter of the reference MapViewOfFile function
bInheritHandle Long, if the handle returned by this function can be inherited by a new process initiated by the current process, this argument is true
Lpname String, specifying the name of the file map object to open


2. Shared Memory Implementation interprocess communication example:
Process 1:
#define Share_memory_size 3145728//3MB
#define Wm_earse_data_write wm_user+110
#define Wm_earse_data_read wm_user+111
typedef struct TAGFILEINFO
{
TCHAR szfilename[max_path];//filename
Long noffset;//Offset
Long nimagesize;//size
int nimagetype;//Image Type
}fileinfo;
typedef struct TAGEARSEIMAGEDATA
{
FileInfo szsrc;//Source file information
FileInfo szdst1;//target file 1
FileInfo szdst2;//target File 2
int nstatus;//State 0, indicating send; 1, indicating acceptance
int bsuccess;//Success 1, indicating success 0, indicating failure
TCHAR szextend[4096];//Extension
}earseimagedata;

Defining shared memory Areas
HANDLE lhShareMemory1 = createfilemapping (HANDLE (0xFFFFFFFF), NULL, page_readwrite,0, share_memory_size,l " Earesimagesharedmemory ");
if (null==lhsharememory1)
{
if (GetLastError ()!=error_already_exists)
{
return 0;
}
}
////////////////////////////////////////////////////////////////////////////////
char* lpbuffer = NULL;
Cximage image1;//cximage Image Processing Class
BOOL BRet = Image1. Load (ssrcfn,cximage_format_tif);
Long ndatasize = 0;
int nimagetype = 6;
Lpbuffer = (char*) mapviewoffile (lhShareMemory1, file_map_write, 0, 0, share_memory_size);
if (lpbuffer)
{
Earseimagedata ImageData;
Long ioffset = sizeof (Earseimagedata);
_tcscpy (IMAGEDATA.SZSRC.SZFILENAME,SSRCFN);
ImageData.szSrc.nImageType = Nimagetype;
ImageData.szSrc.nImageSize = ndatasize;
ImageData.szSrc.nOffset = Ioffset;
Imagedata.nstatus = 0;
imagedata.bsuccess = 0;
memcpy (Lpbuffer,&imagedata,ioffset);
HWND Hfindwnd =:: FindWindow (null,l "earseimage");//Find another window of process 2, send and prepare the data to notify the other process for processing
if (Hfindwnd)
{
:: SendMessage (hfindwnd,wm_earse_data_write,0,0);
}
}

Wm_earse_data_read message processing to receive data processed by Process 2
Lresult Cxxxdlg::onearseimageread (WPARAM wparam,lparam LPARAM)
{
HANDLE lhsharememory;
char* Lpcbuffer;
Lhsharememory = openfilemapping (File_map_read, false,l "earesimagesharedmemory");
if (lhsharememory!=null)
{
Lpcbuffer = (char*) mapviewoffile (lhsharememory, file_map_read, 0, 0, share_memory_size);
if (lpcbuffer!=null)
{
Earseimagedata *pdata = (earseimagedata*) lpcbuffer;
if (PData)
{
if (pdata->bsuccess==1)
{
BOOL BRet1 = M_IMG1. Decode ((BYTE *) (Lpcbuffer+pdata->szdst1.noffset), pdata->szdst1.nimagesize,pdata->szdst1.nimagetype);
BOOL BRet2 = M_img2. Decode ((BYTE *) (Lpcbuffer+pdata->szdst2.noffset), pdata->szdst2.nimagesize,pdata->szdst2.nimagetype);
BRet1 = M_img1. Save (L "D://image1.tif", Pdata->szdst1.nimagetype);
BRet2 = M_img2. Save (L "D://image2.tif", Pdata->szdst2.nimagetype);
}
}
}
}
return 1;
}

if (lpbuffer!=null)
{
UnmapViewOfFile (lpbuffer);
}
if (lhsharememory1!=null)
{
CloseHandle (LhShareMemory1);
}

Process 2:
#define Share_memory_size 3145728//3MB
#define Wm_earse_data_write wm_user+110
#define Wm_earse_data_read wm_user+111
typedef struct TAGFILEINFO
{
TCHAR szfilename[max_path];//filename
Long noffset;//Offset
Long nimagesize;//size
int nimagetype;//Image Type
}fileinfo;
typedef struct TAGEARSEIMAGEDATA
{
FileInfo szsrc;//Source file information
FileInfo szdst1;//target file 1
FileInfo szdst2;//target File 2
int nstatus;//State 0, indicating send; 1, indicating acceptance
int bsuccess;//Success 1, indicating success 0, indicating failure
TCHAR szextend[4096];//Extension
}earseimagedata;

Wm_earse_data_write Message Handler function
HANDLE lhsharememory;
char* Lpcbuffer;
Lhsharememory = openfilemapping (file_map_read| File_map_write, false,l "earesimagesharedmemory");
if (lhsharememory!=null)
{
Lpcbuffer = (char*) mapviewoffile (Lhsharememory, file_map_read| File_map_write, 0, 0, share_memory_size);
if (lpcbuffer!=null)
{Earseimagedata *pdata = (Earseimagedata *) Lpcbuffer;
Cximage IMAGE1,CXTMP1,CXTMP2;
BOOL BRet = Image1. Load (Pdata->szsrc.szfilename,pdata->szsrc.nimagetype);
if (BRet)
{
Cimageprocess g_imageprocess;//cimageprocess for image processing class
if (G_imageprocess.eraseregion (&IMAGE1,&CXTMP1,&CXTMP2))
{
pdata->bsuccess = 1;
Long ioffset = sizeof (Earseimagedata);
BYTE *lpimagedata1= NULL;
BYTE *lpimagedata2 = NULL;
int nimagetype = pdata->szsrc.nimagetype;
Long nimagesize = 0;
Cxtmp1.encode (Lpimagedata1,nimagesize,nimagetype);
Pdata->szdst1.noffset = Ioffset;
Pdata->szdst1.nimagesize = nimagesize;
Pdata->szdst1.nimagetype = Nimagetype;
memcpy (lpcbuffer+ioffset,lpimagedata1,nimagesize);
Ioffset = ioffset+nimagesize;
Cxtmp2.encode (Lpimagedata2,nimagesize,nimagetype);
Pdata->szdst2.noffset = Ioffset;
Pdata->szdst2.nimagesize = nimagesize;
Pdata->szdst2.nimagetype = Nimagetype;
memcpy (lpcbuffer+ioffset,lpimagedata2,nimagesize);
if (lpimagedata1!=null)
{
delete []lpimagedata1;
LpImageData1 = NULL;
}
if (lpimagedata2!=null)
{
delete []lpimagedata2;
LpImageData2 = NULL;
}
}
Else
{
pdata->bsuccess = 0;
}
}
Else
{
pdata->bsuccess = 0;
}
HWND Hfindwnd =:: FindWindow (null,l "unionrecttest");//Find Process 1 window, send message notification data has been processed
if (Hfindwnd)
{
:: SendMessage (hfindwnd,wm_earse_data_read,0,0);
}
}
}
if (lpcbuffer!=null)
{
UnmapViewOfFile (Lpcbuffer);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////

3. Attention Matters
1), share name must be a special name (otherwise it may be because of the system-level object with the same name can cause failure.) Although the probability is not big, but have to defend.
2), in CreateFileMapping (...), openfilemapping (...), MapViewOfFile (..) function, the open mode parameters of the mapping are best consistent.
3), each with MapViewOfFile (...) function mapping once, all must unmapviewoffile (...) A.
4), the use of shared memory in the processing of large data data in the rapid Exchange performance of good performance, in the data reliability and so much higher than the way to send wm_copydata messages, and the WM_COPYDATA message for the small amount of data exchange between processes more convenient and simple.

5, with mapviewoffile processing large files, if the file is too large, such as 400M, you can not map into memory at a time, or there will be 1132 errors, that is, insufficient memory. The reason may be that the operating system cannot find contiguous memory. It is therefore necessary to map the contents of the file to memory, page-by-page.

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.