
window 上跨进程通信主要有几种:共享内存、管道、事件、Socket、邮件槽等。
在了解学习了window的IPC机制,需要实现
-
发送端与接收端跨进程通信;
-
接收端可能处于正在运行或者未运行的状态,并且接收端可能上一次处于运行状态,这一次就可能终止运行了。
发送端:发送消息的一端,并且可能在接收端未启动时候,需要启动接收端;
接收端:负责接收信息的一端,随时可能关闭运行。
最后
-
选择 共享内存机制 来传递消息的具体内容;
-
结合使用 事件 机制 ,事件的一个方法 WaitForSingleObject 负责阻塞等待事件消息,既可以保证跨进程消息的即时性,同时也不需要用死循环来不断的查看共享内存是否有新的内容写入,减少了CPU的负载。
-
如果不熟悉window共享内存,可以了解下: Windows 共享内存映射文件
以及事件:Windows API 创建事件
发送端的流程:
#define BUF_SIZE 1025
const char EventName [] = "EventName";
const char FileMapName [] = "MapFile";
void Sender::start()
{
std::cout<<"发送端"<<std::endl;
fileMapHandler = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, BUF_SIZE, MapFileName);
charBuffer = (char *)MapViewOfFile( fileMapHandler, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
std::string input;
while(1)
{
getline(std::cin, input);
if (!input.empty())
{
strncpy(charBuffer, input.c_str(), BUF_SIZE - 1);
charBuffer[BUF_SIZE - 1] = '\0';
if (isReceiverWork())//判断接收端是否运行, 可以通过判断eventhandler是否存在或者接收端进程是否运行
{
eventHandler = OpenEvent(EVENT_ALL_ACCESS, FALSE, EventName);//获取事件句柄
SetEvent(eventHandler);//发送事件
}
else
{
startupReceiver();//启动接收端
}
}
}
//关闭
UnmapViewOfFile(charBuffer);
CloseHandle(fileMapHandler);
CloseHandle(eventHandler);
}
接收端的流程:
void Receiver::start()
{
std::cout<<"接收端"<<std::endl;
while(1)
{
if (eventHandler != NULL)
{
ResetEvent(eventHandler);//重置为无信号状态
}
fileMapHandler = OpenFileMapping(FILE_MAP_ALL_ACCESS, TRUE, LPCWCHAR(MapFileName));
charBuffer = (char *)MapViewOfFile(fileMapHandler, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
if (fileMapHandler != NULL)
{
if (charBuffer != NULL)
{
cout << "收到内容:"<<charBuffer << endl;
memset(charBuffer, 0, strlen(charBuffer));
}
}
if (eventHandler == NULL)
{
eventHandler = CreateEvent(NULL, FALSE, FALSE, LPCWSTR(EventName));
}
WaitForSingleObject(eventHandler, INFINITE);
}
//关闭
UnmapViewOfFile(charBuffer);
CloseHandle(fileMapHandler);
CloseHandle(eventHandler);
}
以上
-
发送端负责创建共享内存句柄,接收端负责创建事件句柄。
-
发送端先写入共享内存,启动客户端后会默认先读取共享内存,再进入事件等待;这样能解决:在发送端首次想告诉客户端消息,可是客户端还未启动、发送端也还没拿到事件句柄的时候,在接收端第一次启动之后,接收端马上拿取共享内存的内容,实现了第一次的消息通信,以后后续的消息通过事件告知接收端,接收端再从共享内存打开获取具体消息内容。
-
每次发送端都重新获取一次句柄是因为接收端可能随时断开,生成新的一次句柄,解决了接收端状态不稳定的问题。
一点想法
个人对window IPC机制不熟悉,不过相信可能有更好的处理方式,例如邮件槽,边学习边努力吧。
网友评论