Windows 进程共享内存与进程同步

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;
}

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XaoPage

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值