c++和c#之间的共享内存同步
Posted
技术标签:
【中文标题】c++和c#之间的共享内存同步【英文标题】:Shared memory synchronization between c++ and c# 【发布时间】:2016-10-25 10:44:13 【问题描述】:我写了两个小程序。将字符串写入共享内存的 C++ 程序,以及从共享内存读取字符串并将其写入控制台的 C# 程序。
程序运行良好,但目前我在定时循环中写入字符串,然后以相同的频率从另一个定时循环中读取它。
我想做的是创建某种锁定。我想使用信号量/互斥体/任何东西,所以从 C# 我无法在 C++ 程序编写时读取 shm,反之亦然。
我读过一些名为 mutex 和 semamphore 的东西。我可以在两个程序中创建它们,但我真的不知道如何正确使用它们。
C++ 程序: MemoryWriter.h
#ifndef MEMORYWRITER_H_
#define MEMORYWRITER_H_
#include <windows.h>
#include <string>
#include <random>
class MemoryWriter
public:
MemoryWriter(const std::wstring& name, size_t size);
std::string createRandomData() const;
void write(const std::string& data);
private:
char getRandomCharacter() const;
void createSharedMemory();
private:
std::wstring m_memoryName;
size_t m_memorySize = 0;
HANDLE m_shmHandler = 0;
;
#endif // !MEMORYWRITER_H_
MemoryWriter.cpp
#include "MemoryWriter.h"
#include <random>
#include <iostream>
///////////////////////////////////////////////////////////////////////////////
// USING SECTION //
///////////////////////////////////////////////////////////////////////////////
using std::string;
///////////////////////////////////////////////////////////////////////////////
// CONSTANTS SECTION //
///////////////////////////////////////////////////////////////////////////////
const char MinCharacter 'A' ;
const char MaxCharacter 'z' ;
///////////////////////////////////////////////////////////////////////////////
// PUBLIC SECTION //
///////////////////////////////////////////////////////////////////////////////
MemoryWriter::MemoryWriter(const std::wstring& name, size_t size) :
m_memoryName(name),
m_memorySize(size)
createSharedMemory();
string MemoryWriter::createRandomData() const
string data;
for (size_t i = 0; i < m_memorySize; i++)
data += getRandomCharacter();
return data;
void MemoryWriter::write(const string& data)
if (!m_shmHandler)
return;
auto buffer = MapViewOfFile(m_shmHandler, FILE_MAP_ALL_ACCESS, 0, 0, m_memorySize);
if (NULL == buffer)
std::cerr << "Cannot use MapViewOfFile: null buffer." << std::endl;
return;
CopyMemory(buffer, data.c_str(), data.size());
//////////////////////////////////////////////////////////////////////////////
// PRIVATE SECTION //
//////////////////////////////////////////////////////////////////////////////
char MemoryWriter::getRandomCharacter() const
return MinCharacter + rand() % 24;
void MemoryWriter::createSharedMemory()
m_shmHandler = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, m_memoryName.c_str());
if (!m_shmHandler)
m_shmHandler = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
m_memorySize,
m_memoryName.c_str());
main.cpp
#include "MemoryWriter.h"
#include <iostream>
#include <string>
#include <thread>
int main(int argc, char* argv[])
std::wstring memoryName L"shm_1" ;
size_t memorySize 80 ;
MemoryWriter writer(memoryName, memorySize);
while (true)
std::string data;
data = writer.createRandomData();
writer.write(data);
std::cout << "C++: Written in shm - " << data << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
return 0;
C#程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SharedMemoryReader
class Program
static void Main(string[] args)
string shmName = "shm_1";
int shmSize = 80;
var shm = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateOrOpen(shmName, shmSize);
while (true)
var view = shm.CreateViewStream();
if (view == null)
continue;
byte[] data = new byte[shmSize];
view.Read(data, 0, shmSize);
string text = System.Text.Encoding.Default.GetString(data);
System.Console.WriteLine("C#: Read from shm - " + text);
System.Threading.Thread.Sleep(100);
【问题讨论】:
搜索并了解Windows 上的命名信号量。有许多可用的教程和参考资料。 【参考方案1】:您将需要一个命名的同步对象。也许是mutex。
在 C++ 中,您可以调用 CreateMutex,而在 C# 中,Mutex 类会为您处理它。
两个链接都附有示例,如果遇到具体问题,不妨试试看。
【讨论】:
【参考方案2】:我建议使用 named 信号量或 named 互斥量...命名对象是系统范围的
来自 MSDN Interprocess Synchronization:
命名对象为进程共享对象提供了一种简单的方法 把手
【讨论】:
以上是关于c++和c#之间的共享内存同步的主要内容,如果未能解决你的问题,请参考以下文章