利用共享内存实现进程间通信

进程间通信的方法很多,共享内存便是其中的一种,其原理就是把一块物理内存,映射到两个不同进程的虚拟地址空间,这样一个进程对此块内存的操作就能被另一个进程看到。

windows下,使用共享内存有以下几个函数:

CreateFileMapping:用于创建映射文件对象。

OpenFileMapping:打开已存在的文件映射对象。

MapViewOfFile:把文件映射对象转为可读写的void 指针。

对于共享内存的读写,要利用windows提供的内核对象来实现读写进程之间的同步,比如信号量,事件等。在我自己的项目中,由于需要传输大量的数据,希望能够加快数据传输的速度,刚开始我设计的是把共享内存开大一点,比如100个数据单元。然后写进程循环写,读进程只要不遇到当前正在写的单元,就直接读,否则等待。通过实践发现,这种方式不仅没有加快数据传输的速度,反而会出现传输速度时快时慢,随机丢失数据等问题。这是因为我对写进程没有做任何限制,一直循环写。这样做是出于这样的一个前提:假设在同一台机器上的两个进程的速度应该差不多。实际上不能对CPU的调度做任何假设。改为利用事件同步两个进程这种方式后,速度明显比原来快,不丢数据,而且共享内存只需开一个数据单元大小。综上,应该多实践,而不是做一些没有依据的假设。

以下是一些测试的源代码,部分代码来自博客:http://blog.csdn.net/sszgg2006/article/details/8573348

服务端写进程:

#include<iostream>
#include<windows.h>
#include<tchar.h>
using namespace std;

HANDLE hShipFileMapping=NULL;
LPVOID lpShipMem    = NULL;
HANDLE hServerWriteOver = NULL;
HANDLE hClientReadOver  = NULL;

int main(int argc, char const *argv[])
{
    while (!hShipFileMapping)
	{
		hShipFileMapping=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,
			sizeof(int),_T("ShipMem"));
	}

	lpShipMem=MapViewOfFile(hShipFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);

	if (!lpShipMem)
	{
		cout<<"MapView Of File failed : "<<GetLastError()<<endl;

		return -1;
	}
	hServerWriteOver=CreateEvent(NULL,TRUE,FALSE,_T("ServerWriteOver"));
	hClientReadOver=CreateEvent(NULL,TRUE,FALSE,_T("ClientReadOver"));
	if(hServerWriteOver==NULL||hClientReadOver==NULL)
    {
        cout<<"CreateEvent : "<<GetLastError()<<endl;
    }
    int* lp=(int*)lpShipMem;
    int i;
    do
    {
        cin>>i;
        WaitForSingleObject(hClientReadOver,INFINITE);
        *lp=i;
        ResetEvent(hClientReadOver);
        SetEvent(hServerWriteOver);
    }while(i!=0);

    if(hShipFileMapping!=NULL)
        CloseHandle(hShipFileMapping);
    if(hServerWriteOver!=NULL)
        CloseHandle(hServerWriteOver);
    if(hClientReadOver!=NULL)
        CloseHandle(hClientReadOver);

    return 0;

}
客户端读进程:

#include<iostream>
#include<windows.h>
#include<tchar.h>
using namespace std;

HANDLE hShipFileMapping=NULL;
LPVOID lpShipMem    = NULL;
HANDLE hServerWriteOver = NULL;
HANDLE hClientReadOver  = NULL;

int main(int argc, char const *argv[])
{
	while(!hShipFileMapping)
	{
		hShipFileMapping=OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,_T("ShipMem"));
	}
	if(!hShipFileMapping)

		cout<<"open HLAObject FileMapping failed : "<<GetLastError()<<endl;

	lpShipMem=MapViewOfFile(hShipFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);

	if(!lpShipMem)

		cout<<"MapViewOfFile failed :  "<<GetLastError()<<endl;
    hServerWriteOver = CreateEvent(NULL,TRUE,FALSE,_T("ServerWriteOver"));
    hClientReadOver = CreateEvent(NULL,TRUE,FALSE,_T("ClientReadOver"));
    if (NULL == hServerWriteOver ||NULL == hClientReadOver)
    {
        cout << "CreateEvent" << GetLastError() << endl;
    }

    int i;
    int* lp=(int*)lpShipMem;
    do{
        SetEvent(hClientReadOver);
        WaitForSingleObject(hServerWriteOver,INFINITE);
        i=*lp;
        cout<<i<<endl;
        ResetEvent(hServerWriteOver);
    }while(1);

    if(hShipFileMapping!=NULL)
        CloseHandle(hShipFileMapping);
    if(hServerWriteOver!=NULL)
        CloseHandle(hServerWriteOver);
    if(hClientReadOver!=NULL)
        CloseHandle(hClientReadOver);

	return 0;
}



你可能感兴趣的:(C++,同步,共享内存,进程间通信,大数据传输)