【发布时间】:2025-12-11 00:35:01
【问题描述】:
我想以不同进程可以访问相同静态数据的方式实现类:
class Shared()
{
public:
static int GetValue();
static void SetValue(int value);
};
如何使用共享内存来存储内部数据。谁能帮我做到这一点?任何答案将不胜感激。
【问题讨论】:
标签: c++ linux static shared-memory
我想以不同进程可以访问相同静态数据的方式实现类:
class Shared()
{
public:
static int GetValue();
static void SetValue(int value);
};
如何使用共享内存来存储内部数据。谁能帮我做到这一点?任何答案将不胜感激。
【问题讨论】:
标签: c++ linux static shared-memory
示例代码如下所示,这是一个非常基本的实现。课程将解释如何创建、设置/获取单个值和销毁共享内存。可以使用模板将错误检查、通知等添加为策略类。
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
template <key_t KEY, typename T, int COUNT = 1>
class Shm
{
public:
Shm():shm_(0)
{
get();
attach();
}
~Shm()
{
if(shm_ != NULL)
{
shmdt(shm_);
shm_ = 0;
}
}
//Set one element
void SetValue(const T* data, int count = 1)
{
if(sizeof(T)*count > sizeof(T) * COUNT)
{
throw std::runtime_error("Data size greater than shm size");
}
memcpy(shm_, data, sizeof(T)*count);
}
//Get pointer to element
const T* GetValue()
{
T* ptr = new(shm_) T;
return ptr;
}
static void create()
{
if ((shmid_ = shmget(KEY, COUNT*sizeof(T), IPC_CREAT | 0666)) < 0)
{
throw std::runtime_error("Failed create shm");
}
}
static void destroy()
{
get();
if(shmctl(shmid_, IPC_RMID, NULL)<0)
{
perror("shctl");
throw std::runtime_error("Error cannot remove shared memory");
}
shmid_ = -1;
}
private:
static void get()
{
if(shmid_ == -1)
{
if((shmid_ = shmget(KEY, COUNT*sizeof(T), 0666)) < 0)
{
perror("shmget");
throw std::runtime_error("Shared memory not created");
}
}
}
void attach()
{
if ((shm_ = shmat(shmid_, NULL, 0)) == (char *) -1)
{
throw std::runtime_error("Failed attach shm");
}
}
void* shm_;
static int shmid_;
};
template <key_t KEY, typename T, int COUNT>
int Shm<KEY, T, COUNT>::shmid_ = -1;
int main(int argc, char ** argv)
{
if(argc == 2)
{
if(std::string(argv[1]) == "server")
{
int val = 50;
Shm<0x1234, int>::create();
Shm<0x1234, int> shm;
shm.SetValue(&val);
}
else if(std::string(argv[1]) == "client")
{
Shm<0x1234, int> shm;
const int* ptr = shm.GetValue();
std::cout <<"Val = " << *ptr <<std::endl;
Shm<0x1234, int>::destroy();
}
}
else
{
std::cerr<<"Usage shm [server][client]"<<std::endl;
}
return 0;
}
【讨论】:
您真的不想为此手动推出解决方案(特别是如果它必须是可移植的),但幸运的是 boost::interprocess 将为共享内存提供此类功能和更多功能(例如分配器)。
最小示例(未经测试):
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
void* allocate(size_t bytes)
{
static managed_shared_memory segment(create_only, "MySharedMemory", 65536);
return segment.allocate(bytes);
}
【讨论】: