C++ Linux中的共享内存

C++ Linux中的共享内存,c++,linux,static,shared-memory,C++,Linux,Static,Shared Memory,我希望以不同进程可以访问相同静态数据的方式实现类: class Shared() { public: static int GetValue(); static void SetValue(int value); }; 如何使用共享内存存储内部数据。谁能帮我做这个?任何答案都将不胜感激。您确实不想为此手动推出解决方案(特别是如果它必须是可移植的),但幸运的是,这将为共享内存提供此类功能和更多功能(例如分配器) 最小示例(未测试): #包括 使用名称空间boost::interp

我希望以不同进程可以访问相同静态数据的方式实现类:

class Shared()
{
public:
    static int GetValue();
    static void SetValue(int value);
};

如何使用共享内存存储内部数据。谁能帮我做这个?任何答案都将不胜感激。

您确实不想为此手动推出解决方案(特别是如果它必须是可移植的),但幸运的是,这将为共享内存提供此类功能和更多功能(例如分配器)

最小示例(未测试):

#包括
使用名称空间boost::interprocess;
void*分配(大小\u t字节)
{
静态管理共享内存段(仅创建“MySharedMemory”,65536);
返回段。分配(字节);
}

示例代码如下所示,这是一个非常基本的实现。类将解释如何创建、设置/获取单个值以及销毁共享内存。可以使用模板将错误检查、通知等添加为策略类

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模板
类Shm
{
公众:
Shm():Shm(0)
{
get();
附加();
}
~Shm()
{
如果(shm_!=NULL)
{
shmdt(shm_);
shm_=0;
}
}
//设置一个元素
无效设置值(常数T*数据,整数计数=1)
{
if(sizeof(T)*计数>sizeof(T)*计数)
{
抛出std::runtime_错误(“数据大小大于shm大小”);
}
memcpy(shm_u2;、数据、大小f(T)*计数);
}
//获取指向元素的指针
常量T*GetValue()
{
T*ptr=new(shm_uut);
返回ptr;
}
静态void create()
{
如果((shmid_=shmget(键,计数*sizeof(T),IPC_创建| 0666))<0)
{
抛出std::运行时_错误(“创建shm失败”);
}
}
静态空洞破坏()
{
get();
if(shmctl(shmid、IPC、RMID、NULL)
#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;
}