我想以不同进程可以访问相同静态数据的方式实现类:
class Shared()
{
public:
static int GetValue();
static void SetValue(int value);
};
如何使用共享内存来存储内部数据来做到这一点。有人可以帮我做到这一点吗?任何答案将不胜感激。
最佳答案
示例代码如下所示,这是一个非常基本的实现。类(class)将解释如何创建、设置/获取单个值以及销毁共享内存。错误检查、通知等可以使用模板添加为策略类。
#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;
}
关于c++ - Linux 中的共享内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33876164/