2021-01-04

定义

共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同CPU访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,共享内存需要立即更新。共享内存是 Unix下的多进程之间的通信方法,可用于同一程序中的多进程或多程序中。

示例

c#应用

SharedMemory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ShareMemoryCs
{
public class ShareMemory
{
public enum RETVAL
{
SUCCESS= 0,
FAILURE = -10000,
}
private System.IO.MemoryMappedFiles.MemoryMappedFile mmf;
private System.IO.MemoryMappedFiles.MemoryMappedViewAccessor viewAccessor;
public int MemorySize
{
get;
set;
}

    public string MemoryName
    {
        set;
        get;
    }

    public ShareMemory()
    {
        MemoryName = "test_share_memory";
        MemorySize = 1 << 10 << 16;
    }

    public int Init(string strMemoryName)
    {
        if (String.IsNullOrEmpty(strMemoryName))
            return RETVAL.FAILURE.GetHashCode();
        MemoryName = strMemoryName;
        mmf = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen(MemoryName, MemorySize, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.ReadWrite);
        viewAccessor = mmf.CreateViewAccessor(0, MemorySize);

        return RETVAL.SUCCESS.GetHashCode();
    }

    public int InputData(string strTxt)
    {
        viewAccessor.Write(0, strTxt.Length);
        viewAccessor.WriteArray<char>(0, strTxt.ToArray(), 0, strTxt.Length);
        return RETVAL.SUCCESS.GetHashCode();
    }

    public int OutputData(out string strTxt)
    {
        //这里要指定Unicode编码否则会出问题
        //读取字符
        int length = viewAccessor.ReadInt32(0);
        char[] charsInMMf = new char[length];
        viewAccessor.ReadArray<char>(0, charsInMMf, 0, length);
        strTxt = String.Join("", charsInMMf);
        strTxt = strTxt.TrimEnd('\0');
        return RETVAL.SUCCESS.GetHashCode();
    }
    public void ClearMemory()
    {
        char[] charsInMMf = new char[MemorySize];
        viewAccessor.WriteArray<char>(0, charsInMMf, 0, MemorySize/2);
    }
    public void Dispose()
    {
        if(viewAccessor!=null)
            viewAccessor.Dispose();
        if (mmf != null)
            mmf.Dispose();
    }
}

}

c++应用

SharedMemory.h

#pragma once

#include
#include
#include
#include

#ifdef SHAREMEMORY_EXPORTS
#define SHAREMEMORY_DLL __declspec(dllexport)
#else
#define SHAREMEMORY_DLL __declspec(dllimport)
#endif

enum ErrorDefine
{
SUCCESS = 0,
FAILURE = -50000,

};

struct ShareMemoryParam
{
wchar_t strName[CHAR_MAX];
void* m_pBuffer;
void* m_hMap;
ShareMemoryParam()
{
memset(strName, 0, CHAR_MAX*sizeof(wchar_t));
m_pBuffer = NULL;
m_hMap = NULL;
}
};

class SHAREMEMORY_DLL CShareMemory
{
public:
CShareMemory();
~CShareMemory();

public:
int Init(std::wstring& strName);
int InputData(std::wstring& strTxt);
int OutputData(std::wstring& strTxt);
void ClearMemroy();
void Dispose();
void SetShareMemoryName(std::wstring& strName);

private:
std::wstring m_sShareMemoryName;
int m_MemorySize;
std::map<int, ShareMemoryParam> m_smp;
};

SharedMemory.cpp

// ShareMemory.cpp : 定义 DLL 应用程序的导出函数。
//

#include “stdafx.h”
#include “ShareMemory.h”

CShareMemory::CShareMemory() {
m_sShareMemoryName = L"test_share_memeory";
m_MemorySize = 1 << 10 << 16;
}
CShareMemory::~CShareMemory()
{
Dispose();
}

int CShareMemory::Init(std::wstring& strName)
{
if (!strName.empty())
m_sShareMemoryName = strName;

ShareMemoryParam _smp;
HANDLE hMap;
LPVOID pBuffer;
// 首先试图打开一个命名的内存映射文件对象  
hMap = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, (LPCWSTR)m_sShareMemoryName.c_str());
if (NULL == hMap)
{
	// 打开失败,创建之
	hMap = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, m_MemorySize, (LPCWSTR)m_sShareMemoryName.c_str());
	// 打开成功,映射对象的一个视图,得到指向共享内存的指针
	pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, m_MemorySize);
}
else
{
	pBuffer = ::MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}

memcpy(_smp.strName, m_sShareMemoryName.c_str(), m_sShareMemoryName.length()*sizeof(wchar_t));
_smp.m_hMap = hMap;
_smp.m_pBuffer = pBuffer;
m_smp.insert(std::pair<int, ShareMemoryParam>();
if (pBuffer)
	return SUCCESS;
else
	return FAILURE;

}
int CShareMemory::InputData(std::wstring& strTxt)
{
if (strTxt.length() * sizeof(wchar_t) > m_MemorySize)
return FAILURE;
//写数据
for (int i = 0; i < m_smp.size(); i++)
{
if (std::wstring(m_smp[i].strName) == m_sShareMemoryName)
memcpy(m_smp[i].m_pBuffer, strTxt.c_str(), (strTxt.length() + 1) * sizeof(wchar_t));
}
return SUCCESS;
}
int CShareMemory::OutputData(std::wstring& strTxt)
{
//写数据
for (int i = 0; i < m_smp.size(); i++)
{
if (std::wstring(m_smp[i].strName) == m_sShareMemoryName)
strTxt = std::wstring((wchar_t*)m_smp[i].m_pBuffer);
}
return SUCCESS;
}
void CShareMemory::ClearMemroy()
{
for (int i = 0; i < m_smp.size(); i++)
{
if (std::wstring(m_smp[i].strName)==m_sShareMemoryName)
{
memset(m_smp[i].m_pBuffer, 0, m_MemorySize);
break;
}
}
}
void CShareMemory::Dispose()
{
// 解除文件映射,关闭内存映射文件对象句柄
for (int i = 0; i < m_smp.size(); i++)
{
if (m_smp[i].m_pBuffer)
::UnmapViewOfFile(m_smp[i].m_pBuffer);
if (m_smp[i].m_hMap)
::CloseHandle(m_smp[i].m_hMap);
m_smp[i].m_pBuffer = NULL;
m_smp[i].m_hMap = NULL;
}
}

void CShareMemory::SetShareMemoryName(std::wstring& strName)
{
m_sShareMemoryName = strName;
}

总结

以上是基本的共享内存应用,通过设定共享内存名称,访问映射的内存中数据,在程序中或程序间均可自由快速访问。
后续待增加功能点:共享内存没有任何的同步与互斥机制,所以需要使用信号量来实现对共享内存的存取的同步。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xin-yan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值