Windows共享内存
实现步骤及关键函数:
//1 创建共享内存对象:
//使用 CreateFileMapping 函数创建一个文件映射对象。文件映射对象可以是具有名称的对象,以便在不同的进程之间共享。
//写端使用CreateFileMapping创建共享内存
HANDLE hFileMapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // 文件句柄,使用 INVALID_HANDLE_VALUE 表示不与文件关联
NULL, // 安全性描述符,默认为 NULL
PAGE_READWRITE, // 读写权限
0, // 高位 DWORD 文件大小
sizeof(YOUR_DATA_TYPE), // 低位 DWORD 文件大小 ——你想共享的内存大小
L"SharedMemoryName"); // 共享内存对象名称
//读端使用则是使用OpenFileMapping获取已经创建的共享内存
hFile_mapping = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // 物理文件句柄
NULL, // 默认安全级别
L"ShareMemory" // 共享内存名称
);
//2.将共享内存映射到进程地址空间:
//使用 MapViewOfFile 函数将共享内存映射到进程的地址空间中。
LPVOID pSharedMemory = MapViewOfFile(
hFileMapping, // 文件映射对象句柄
FILE_MAP_ALL_ACCESS, // 访问权限
0, // 高位 DWORD 文件偏移
0, // 低位 DWORD 文件偏移
0); // 映射到整个文件
//3.使用共享内存:
//现在,你可以在不同的进程中通过对共享内存进行读写来实现数据共享
//4.关闭句柄和解除映射:
//在使用完共享内存后,需要关闭文件映射对象句柄和解除映射。
CloseHandle(hFileMapping); // 关闭文件映射对象句柄
UnmapViewOfFile(pSharedMemory); // 解除映射
完整的读写端代码:
// 写端代码
#include <Windows.h>
#include <iostream>
#include <string>
class Share_Memory {
public:
Share_Memory(unsigned long _memory_size) :
memory_size(_memory_size),
pBuff(NULL),
hFile_mapping()
{
hFile_mapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // 物理文件句柄
NULL, // 默认安全级别
PAGE_READWRITE, // 可读可写
0, // 高位文件大小
memory_size, // 低位文件大小
"ShareMemory" // 共享内存名称
);
pBuff = MapViewOfFile(
hFile_mapping, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
memory_size
);
}
~Share_Memory() {
// 解除文件映射
UnmapViewOfFile(pBuff);
// 关闭内存映射文件对象句柄
CloseHandle(hFile_mapping);
}
void write_memory(char* pin_buffer, size_t size) {
memcpy(pBuff, pin_buffer, size);
}
private:
unsigned long memory_size;
LPVOID pBuff;
HANDLE hFile_mapping;
};
int main() {
char write_buff[] = "write"; //写入共享内存的内容
Share_Memory share_mem_write(1024); //创建共享内存
share_mem_write.write_memory(write_buff, sizeof(write_buff)); //写共享内存
system("pause"); //保持,确保读端
return 0;
}
// 读端代码
#pragma once
#include <Windows.h>
#include <iostream>
#include <string>
class Share_Memory {
public:
Share_Memory() :
pBuff(NULL),
hFile_mapping()
{
hFile_mapping = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // 物理文件句柄
NULL, // 默认安全级别
L"ShareMemory" // 共享内存名称
);
if (!hFile_mapping) {
fprintf(stderr, "%s: %d OpenFileMapping failed\n", __FILE__, __LINE__);
exit(-1);
}
pBuff = MapViewOfFile(
hFile_mapping, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
0
);
}
~Share_Memory()
{
// 解除文件映射
UnmapViewOfFile(pBuff);
// 关闭内存映射文件对象句柄
CloseHandle(hFile_mapping);
}
std::string read_memory()
{
char* read_buffer = (char*)malloc(memory_size);
memcpy(read_buffer, pBuff, memory_size);
std::string ret_str(read_buffer);
delete read_buffer;
read_buffer = nullptr;
return ret_str;
}
private:
LPVOID pBuff;
HANDLE hFile_mapping;
};
int main() {
Share_Memory share_mem_read();
std::cout << share_mem_read.read_memory() << std::endl;
return 0;
}
读写端进程的同步——互斥体
上述代码实现的单次的读写共享内存,但是更多情况下要对共享内存进行重复的读写操作,则涉及到了进程的同步
实现步骤及关键函数:
//1. 创建互斥体对象:
//使用 CreateMutex 函数创建一个互斥体对象。
HANDLE hMutex = CreateMutex(
NULL, // 默认安全性
FALSE, // 初始状态为非锁定
L"MutexName"); // 互斥体对象名称
//2.使用互斥体:
//在需要对共享资源进行访问的地方,使用 WaitForSingleObject 函数等待互斥体,表示要访问共享资源。使用 ReleaseMutex 函数释放互斥体,表示访问结束。
// 等待互斥体
WaitForSingleObject(hMutex, INFINITE);
// 访问共享资源的代码
// 释放互斥体
ReleaseMutex(hMutex);
//3.关闭互斥体句柄:
//在程序结束时,需要关闭互斥体句柄。
CloseHandle(hMutex);
完整的读写端代码:
//写段
//--头文件部分——share_memory.h-----------------------------------
#include <Windows.h>
#include <iostream>
#include <string>
class Share_Memory {
public:
~Share_Memory(unsigned long _memory_size);
std::string read_memory();
void write_memory(char* pin_buffer, size_t size);
private:
Share_Memory();
unsigned long memory_size;
LPVOID pBuff;
HANDLE hFile_mapping;
public:
HANDLE pMutex;
};
//--源文件部分——share_memory.cpp-----------------------------------
#include "share_memory.h"
Share_Memory* Share_Memory::sh_mem_instance = nullptr;
Share_Memory::Share_Memory() :
memory_size(_memory_size),
pBuff(NULL),
hFile_mapping(),
pMutex(CreateMutex(NULL, false, "pMutex")),
{
hFile_mapping = CreateFileMapping(
INVALID_HANDLE_VALUE, // 物理文件句柄
NULL, // 默认安全级别
PAGE_READWRITE, // 可读可写
0, // 高位文件大小
memory_size, // 低位文件大小
"ShareMemory" // 共享内存名称
);
pBuff = MapViewOfFile(
hFile_mapping, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
memory_size
);
}
Share_Memory::~Share_Memory()
{
// 解除文件映射
UnmapViewOfFile(pBuff);
// 关闭内存映射文件对象句柄
CloseHandle(hFile_mapping);
}
std::string Share_Memory::read_memory()
{
char* read_buffer = (char*)malloc(memory_size);
memcpy(read_buffer, pBuff, memory_size);
std::string ret_str(read_buffer);
delete read_buffer;
read_buffer = nullptr;
return ret_str;
}
void Share_Memory::write_memory(char* pin_buffer, size_t size)
{
memcpy(pBuff, pin_buffer, size);
}
int main(){
Share_Memory share_mem_w(1024);
char buf[32];
int i = 0;
while (true) {
sprintf(buf, "write_%d", i);
WaitForSingleObject(share_mem_w.pMutex, INFINITE);
//如果想让写端在拿不到互斥锁的情况下转而执行代码
//可以将WaitForSingleObject的第二个参数设置为0,根据此函数的返回值来判断
//DWORD ret_state = WaitForSingleObject(sh_mem->pMutex, 0);
//if (ret_state == WAIT_TIMEOUT) return;
share_mem_w.write_memory(buf, sizeof(buf));
ReleaseMutex(share_mem_w.pMutex);
i++;
}
system("pause");
return 0;
}
// 读端
//--头文件部分——share_memory.h-----------------------------------
#include <Windows.h>
#include <iostream>
#include <string>
class Share_Memory {
public:
Share_Memory();
~Share_Memory();
std::string read_memory();
void write_memory(char* pin_buffer, size_t size);
void reset_memory();
private:
LPVOID pBuff;
HANDLE hFile_mapping;
public:
HANDLE pMutex;
};
//--源文件部分——share_memory.cpp-----------------------------------
#include "share_memory.h"
Share_Memory::Share_Memory() :
pBuff(NULL),
hFile_mapping(),
pMutex(CreateMutex(NULL, false, L"pMutex")),
{
if (!pMutex) {
fprintf(stderr, "%s: %d Create synchronization object failed\n", __FILE__, __LINE__);
}
hFile_mapping = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // 物理文件句柄
NULL, // 默认安全级别
L"ShareMemory" // 共享内存名称
);
if (!hFile_mapping) {
fprintf(stderr, "%s: %d OpenFileMapping failed\n", __FILE__, __LINE__);
exit(-1);
}
pBuff = MapViewOfFile(
hFile_mapping, // 共享内存的句柄
FILE_MAP_ALL_ACCESS, // 可读写许可
0,
0,
0 //本例中,填写 BIG_BUF_SIZE 的效果等价于此处填 0
);
}
Share_Memory::~Share_Memory()
{
// 解除文件映射
UnmapViewOfFile(pBuff);
// 关闭内存映射文件对象句柄
CloseHandle(hFile_mapping);
}
std::string Share_Memory::read_memory()
{
char* read_buffer = (char*)malloc(memory_size);
memcpy(read_buffer, pBuff, memory_size);
std::string ret_str(read_buffer);
delete read_buffer;
read_buffer = nullptr;
return ret_str;
}
void Share_Memory::write_memory(char* pin_buffer, size_t size)
{
memcpy(pBuff, pin_buffer, size);
}
void Share_Memory::reset_memory()
{
char reset_info[] = "read done";
memcpy(pBuff, reset_info, sizeof(reset_info));
}
int main(){
Share_Memory share_mem_r();
while (true) {
WaitForSingleObject(share_mem_r.pMutex, INFINITE);
std::cout << share_mem_w.read_memory() << std::endl;
ReleaseMutex(share_mem_r.pMutex);
}
system("pause");
return 0;
}