一、知识点
主要使用了以下几个函数,具体入参等含义可以百度
1.CreateFileMapping、OpenFileMapping、MapViewOfFile
2.CreateEvent、SetEvent、ResetEvent、WaitForSingleObject
二、功能
逻辑很简单,就是:
1.先根据名称打开共享内存,打开失败的话,就去创建。然后调用MapViewOfFile获取共享内存的地址
2.启动一个线程,使用事件检测共享内存是否有数据,如果有数据的话,就去读取,然后调用数据处理函数进行处理
代码:
ShareMemory.h
#ifndef SHAREMEMORY_H
#define SHAREMEMORY_H
#include <string>
#include <thread>
#include <memory>
#include "Windows.h"
class ShareMemory
{
public:
ShareMemory(std::wstring strKey, unsigned int nSize = 1024);
~ShareMemory();
void registeReceiver(std::function<void(char *)> pfunReceiver);
void writeData(char *data, int nLength);
private:
void readData();
private:
std::shared_ptr<std::thread> m_ptrReadThread;
bool m_bThreadRunning = true;
HANDLE m_hMapFile = nullptr;
LPVOID m_buffer = nullptr;
std::function<void(char *)> m_pfunReceiver = nullptr;
std::wstring m_strUniqueId;
HANDLE m_writeEvent = nullptr;
};
#endif
ShareMemory.cpp
#include "stdafx.h"
#include "ShareMemory.h"
#include <iostream>
ShareMemory::ShareMemory(std::wstring strKey, unsigned int nSize)
{
m_strUniqueId = std::move(strKey);
m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, m_strUniqueId.c_str());
if (!m_hMapFile)
{
m_hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, nSize, m_strUniqueId.c_str());
}
if (m_hMapFile)
{
m_buffer = MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, nSize);
if (!m_buffer)
{
CloseHandle(m_hMapFile);
}
else
{
std::wstring strWriteKey = m_strUniqueId;
strWriteKey.append(L"_write");
m_writeEvent = CreateEvent(NULL, TRUE, FALSE, strWriteKey.c_str());
memset(m_buffer, 0, nSize);
m_ptrReadThread = std::make_shared<std::thread>(std::bind(&ShareMemory::readData, this));
}
}
}
ShareMemory::~ShareMemory()
{
if (m_buffer)
{
UnmapViewOfFile(m_buffer);
m_buffer = nullptr;
}
if (m_hMapFile)
{
CloseHandle(m_hMapFile);
m_hMapFile = nullptr;
}
if (m_writeEvent)
{
CloseHandle(m_writeEvent);
m_writeEvent = nullptr;
}
}
void ShareMemory::registeReceiver(std::function<void(char *)> pfunReceiver)
{
m_pfunReceiver = pfunReceiver;
}
void ShareMemory::writeData(char *data, int nLength)
{
if (m_writeEvent)
{
memcpy(m_buffer, data, nLength);
SetEvent(m_writeEvent);
}
}
void ShareMemory::readData()
{
if (!m_writeEvent)
{
return;
}
while (m_bThreadRunning)
{
DWORD dwWaitResult = WaitForSingleObject(m_writeEvent, INFINITE);
switch (dwWaitResult)
{
// Event object was signaled
case WAIT_OBJECT_0:
{
if (m_pfunReceiver)
{
char *data = (char*)m_buffer;
int nLen = strlen(data);
m_pfunReceiver(data);
memset(m_buffer, 0, nLen);
ResetEvent(m_writeEvent);
}
break;
}
default:
std::cout<<"Wait error :" << GetLastError()<<std::endl;
break;
}
}
}
写数据进程
int main(int *argc, char *argv[])
{
ShareMemory sm(L"mysharememory");
while (true)
{
char in[100];
std::cin >> in;
sm.writeData(in, strlen(in));
}
system("pause");
return 0;
}
读数据进程
int main(int *argc, char *argv[])
{
ShareMemory sm(L"mysharememory");
std::string i = std::string(argv[1]);
sm.registeReceiver([](char *data) {
std::cout << data << std::endl;
});
system("pause");
return 0;
}
三、问题
这段代码逻辑比较简单,已经实现共享内存的数据读写,但是还是有很多场景没有处理,接下来我们会对它进行修改