c++进程通信--共享内存详细实现

学习记录:共享内存实现

共享内存类,头文件:

#include <Windows.h>
#include <iostream>
#include <vector>

typedef struct ChunkInfo
{
	int read;   //读的位置,为了确定读那一块儿的区域,必须在首端设置一个读的指针(写的也应该)
	int write;
	int chunksize[8];   //还可以有其他的信息(这里写了每个块写入的区域size)
}ChunkInfo;

#define ShareMemoryLen 8//一共8块区域,使用循环数组进行遍历读取
#define ShareMemorySize 1920*1080*3*8*8+sizeof(ChunkInfo)  //8块1920*1080*3*8大小的内存写入区域
#define ShareMemoryName L"ShareMemoryName"
using std::vector;

class ShareMemory
{
public:
	ShareMemory(bool bval);//判断是创建的还是非创建
	void Init(int size=0);
	bool Read(int &size,uint8_t* ch);
	bool Write(int &size, uint8_t* ch);

private:
	int   m_size;
	void* m_buffer;
	bool  m_isCreate;
};

函数实现:

#include "ShareMemory.h"

ShareMemory::ShareMemory(bool bval)
	:m_isCreate(bval)//共享内存创建相同名字只能有一个(一个创建剩下的来读取)
{
}

void ShareMemory::Init(int size=0)//进行初始化
{
	if (size == 0)
		m_size = ShareMemorySize;
	if (m_isCreate)//创建共享内存
	{
		//创建成功,返回创建的内存映射文件的句柄
		HANDLE handle = CreateFileMapping(	//创建内存映射文件的内核对象
			INVALID_HANDLE_VALUE,			//文件句柄,默认
			NULL,							//安全描述符,没有写null(可以用安全描述符来指定什么类型的程序(例如:system,server,user)可以访问该共享内存)
			PAGE_READWRITE,					//映射对象类型
			0,								//文件映射最大长度的高32位
			m_size,							//文件映射最大长度的低32位
			ShareMemoryName					//文件映射对象的名称
		);
		if (handle)
		{
			//通过创建返回的句柄将内存映射文件映射到进程的虚拟地址中(返回共享内存起始地址)
			m_buffer = (void*)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, m_size);
		}
	}
	else
	{
		HANDLE handle = OpenFileMapping(	//如果已经创建好了,就直接打开独影的内存映射对象
			FILE_MAP_READ | FILE_MAP_WRITE,	//数据的访问方式
			FALSE,							//是否继承句柄
			ShareMemoryName					//文件映射对象名称
		);
		if (handle)
		{
			m_buffer = (void*)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, m_size);
		}
	}
	ChunkInfo* chunkinfo = (ChunkInfo*)m_buffer;
	chunkinfo->read = 0;		
	chunkinfo->write = 0;
	for (int i = 0; i < 8; ++i)
		chunkinfo->chunksize[i] = -1;
}

bool ShareMemory::Read(int &size, uint8_t* ch)
{
	ChunkInfo* chunkinfo = (ChunkInfo*)m_buffer;
	int pread = chunkinfo->read;
	int pwrite = chunkinfo->write;
	//判断循环队列是否为空
	if (pread == pwrite)
	{
		std::cout << "共享内存为空,读取失败" << std::endl;
		return false;
	}
	else
	{
		size = chunkinfo->chunksize[chunkinfo->read];
		if (size < 0)
			return false;
		chunkinfo->read = (chunkinfo->read + 1) % ShareMemoryLen;
		size_t pos = (m_size - sizeof(ChunkInfo)) / ShareMemoryLen * (chunkinfo->read);//求得 除去共享内存中数据头的相对位置
		//找到读取的起始位置
		uint8_t* ptrRead = (uint8_t*)m_buffer + sizeof(ChunkInfo) + pos;
		if (0 == memcpy_s(ptrRead, size, ch, size))//赋值
		{
			std::cout << "read success" << std::endl;
			return true;
		}
		else
		{
			std::cout << "read fail" << std::endl;
			return false;
		}
	}
}

bool ShareMemory::Write(int& size, uint8_t* ch)
{
	ChunkInfo* chunkinfo = (ChunkInfo*)m_buffer;
	if ((chunkinfo->read + 1) % 8 == chunkinfo->write)	//循环队列,牺牲一个空间来判断满
	{
		std::cout << "共享内存已满,写入失败" << std::endl;
		return false;
	}
	else
	{
		chunkinfo->chunksize[chunkinfo->write] = size;
		chunkinfo->write = (chunkinfo->write + 1) % ShareMemoryLen;
		size_t pos = (m_size - sizeof(ChunkInfo)) / ShareMemoryLen * chunkinfo->write;
		uint8_t* ptrWrite = (uint8_t*)m_buffer + pos + sizeof(ChunkInfo);
		if (0 == memcpy_s(ch, size, ptrWrite, size))
		{
			std::cout << "write success" << std::endl;
			return true;
		}
		else
		{
			std::cout << "write success" << std::endl;
			return false;
		}
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值