C++ boost::interprocess::shared_memory_object 分析详解

博客介绍了C++使用boost库创建进程间共享内存的常见方式,强调要注意读写间的时间同步,还给出了boost::interprocess::shared_memory_object类的文档链接、share momory创建模板链接以及Mapping File's Contents In Memory相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于C++ 使用boost库,创建进程间的共享内存,是一种常见的方式,需要注意的就是读写之间的的时间同步

1. boost::interprocess::shared_memory_object 类

// In header: <boost/interprocess/shared_memory_object.hpp>


class shared_memory_object {
public:
  // construct/copy/destruct
  shared_memory_object();
  shared_memory_object(create_only_t, const char *, mode_t, 
                       const permissions & = permissions());
  shared_memory_object(open_or_create_t, const char *, mode_t, 
                       const permissions & = permissions());
  shared_memory_object(open_only_t, const char *, mode_t);
  shared_memory_object(shared_memory_object &&);
  shared_memory_object & operator=(shared_memory_object &&);
  ~shared_memory_object();

  // public member functions
  void swap(shared_memory_object &);
  void truncate(offset_t);
  const char * get_name() const;
  bool get_size(offset_t &) const;
  mode_t get_mode() const;
  mapping_handle_t get_mapping_handle() const;

  // public static functions
  static bool remove(const char *);
};

https://www.boost.org/doc/libs/1_70_0/doc/html/boost/interprocess/shared_memory_object.html

 

2. share momory创建模板

https://www.boost.org/doc/libs/1_70_0/doc/html/interprocess/sharedmemorybetweenprocesses.html

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <cstring>
#include <cstdlib>
#include <string>

int main(int argc, char *argv[])
{
   using namespace boost::interprocess;

   if(argc == 1){  //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;

      //Create a shared memory object.
      shared_memory_object shm (create_only, "MySharedMemory", read_write);

      //Set size
      shm.truncate(1000);

      //Map the whole shared memory in this process
      mapped_region region(shm, read_write);

      //Write all the memory to 1
      std::memset(region.get_address(), 1, region.get_size());

      //Launch child process
      std::string s(argv[0]); s += " child ";
      if(0 != std::system(s.c_str()))
         return 1;
   }
   else{
      //Open already created shared memory object.
      shared_memory_object shm (open_only, "MySharedMemory", read_only);

      //Map the whole shared memory in this process
      mapped_region region(shm, read_only);

      //Check that memory was initialized to 1
      char *mem = static_cast<char*>(region.get_address());
      for(std::size_t i = 0; i < region.get_size(); ++i)
         if(*mem++ != 1)
            return 1;   //Error checking memory
   }
   return 0;
}

 

3. Mapping File's Contents In Memory

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
#include <cstddef>
#include <cstdlib>

int main(int argc, char *argv[])
{
   using namespace boost::interprocess;

   //Define file names
   const char *FileName  = "file.bin";
   const std::size_t FileSize = 10000;

   if(argc == 1){ //Parent process executes this
      {  //Create a file
         file_mapping::remove(FileName);
         std::filebuf fbuf;
         fbuf.open(FileName, std::ios_base::in | std::ios_base::out
                              | std::ios_base::trunc | std::ios_base::binary);
         //Set the size
         fbuf.pubseekoff(FileSize-1, std::ios_base::beg);
         fbuf.sputc(0);
      }

      //Remove on exit
      struct file_remove
      {
         file_remove(const char *FileName)
            : FileName_(FileName) {}
         ~file_remove(){ file_mapping::remove(FileName_); }
         const char *FileName_;
      } remover(FileName);

      //Create a file mapping
      file_mapping m_file(FileName, read_write);

      //Map the whole file with read-write permissions in this process
      mapped_region region(m_file, read_write);

      //Get the address of the mapped region
      void * addr       = region.get_address();
      std::size_t size  = region.get_size();

      //Write all the memory to 1
      std::memset(addr, 1, size);

      //Launch child process
      std::string s(argv[0]); s += " child ";
      if(0 != std::system(s.c_str()))
         return 1;
   }
   else{  //Child process executes this
      {  //Open the file mapping and map it as read-only
         file_mapping m_file(FileName, read_only);

         mapped_region region(m_file, read_only);

         //Get the address of the mapped region
         void * addr       = region.get_address();
         std::size_t size  = region.get_size();

         //Check that memory was initialized to 1
         const char *mem = static_cast<char*>(addr);
         for(std::size_t i = 0; i < size; ++i)
            if(*mem++ != 1)
               return 1;   //Error checking memory
      }
      {  //Now test it reading the file
         std::filebuf fbuf;
         fbuf.open(FileName, std::ios_base::in | std::ios_base::binary);

         //Read it to memory
         std::vector<char> vect(FileSize, 0);
         fbuf.sgetn(&vect[0], std::streamsize(vect.size()));

         //Check that memory was initialized to 1
         const char *mem = static_cast<char*>(&vect[0]);
         for(std::size_t i = 0; i < FileSize; ++i)
            if(*mem++ != 1)
               return 1;   //Error checking memory
      }
   }

   return 0;
}

 

 

<think>我们被要求解释一段使用Boost.Interprocess库创建共享内存的C++代码。 代码片段: boost::interprocess::shared_memory_object::remove(PLAYING_ADDRESS); boost::interprocess::managed_shared_memory shm(boost::interprocess::create_only, PLAYING_ADDRESS, 1024 * 1024); 解释如下: 第一行:删除(移除)名为PLAYING_ADDRESS的共享内存对象。 第二行:创建一个新的名为PLAYING_ADDRESS的托管共享内存区域,大小为1MB(1024*1024字节),且以独占模式创建(如果已存在则失败)。 详细说明: 1. `shared_memory_object::remove(const char *name)`: - 作用:删除名为`name`的共享内存对象。这是一个静态函数。 - 必要性:在创建新的共享内存之前,确保系统中没有同名的共享内存残留(可能由于之前的程序异常退出导致)。 - 注意:如果共享内存不存在,该函数不会报错(安全)。 2. `managed_shared_memory`的构造函数参数: - 第一个参数:`boost::interprocess::create_only`,表示只创建(如果已经存在则抛出异常)。 - 第二个参数:共享内存的名称(字符串),即`PLAYING_ADDRESS`。 - 第三个参数:共享内存的大小(字节数),这里是1MB(1024*1024)。 3. 创建托管共享内存: - `managed_shared_memory`是一个封装类,用于管理具有高级特性的共享内存(如动态内存分配、容器支持等)。 - 创建后,该共享内存区域可以被其他进程通过名称访问(但此处使用`create_only`,所以只能由创建者使用,其他进程需要使用`open_only`或`open_or_create`)。 4. 异常安全: - 如果`remove`后立即创建,但创建失败(比如内存不足),则程序会抛出异常(如`boost::interprocess::interprocess_exception`)。 5. 生命周期: - 共享内存对象会一直存在,直到被显式删除(`remove`)或系统重启。 - 因此,在程序启动时调用`remove`是清理旧共享内存的常见做法。 6. 使用场景: - 常用于进程间通信(IPC),允许不同进程读写同一块内存区域。 注意事项: - 在多进程同时启动时,可能存在竞态条件(一个进程在另一个进程创建后调用remove)。但此处因为是顺序执行,且先remove再创建,所以通常安全(前提是其他进程不会同时操作)。 代码示例作用总结: 确保创建前无残留共享内存,然后创建1MB大小的托管共享内存。 根据要求,在最后提出3-5个相关问题。</think>这段代码使用Boost.Interprocess库创建和管理共享内存,具体含义如下: ### 代码解析 ```cpp // 1. 删除可能已存在的共享内存对象 boost::interprocess::shared_memory_object::remove(PLAYING_ADDRESS); // 2. 创建新的托管共享内存区域 boost::interprocess::managed_shared_memory shm( boost::interprocess::create_only, // 创建模式:独占创建 PLAYING_ADDRESS, // 共享内存标识名 1024 * 1024 // 内存大小:1MB (1024KB) ); ``` ### 详细说明 1. **`shared_memory_object::remove(PLAYING_ADDRESS)`** - **功能**:删除指定名称的共享内存段 - **必要性**: - 确保后续创建操作不会因重名冲突而失败 - 清理可能残留的旧共享内存(如程序崩溃后未释放的资源) - **注意**:若共享内存不存在,此操作不会报错(安全) 2. **`managed_shared_memory` 构造函数** - **参数1**: `boost::interprocess::create_only` - 创建模式:独占创建(若同名共享内存已存在则抛出异常) - 替代选项:`open_only`(仅打开)或 `open_or_create`(打开或创建) - **参数2**: `PLAYING_ADDRESS` - 共享内存的唯一标识符(通常为字符串常量) - 不同进程通过此名称访问同一块共享内存 - **参数3**: `1024 * 1024` - 分配的共享内存大小(1MB) - 必须满足系统限制(Linux默认最小4096字节) ### 工作原理示意图 ```mermaid graph LR A[进程A] -->|1. remove| C[内核共享内存区] A -->|2. create| C B[进程B] -->|3. open| C C[共享内存 PLAYING_ADDRESS] ``` ### 关键特性 | **特性** | **说明** | **典型应用场景** | |----------|----------|------------------| | **自动管理** | `managed_shared_memory` 封装底层细节 | 简化共享内存操作 | | **跨进程通信** | 不同进程通过相同名称访问 | IPC数据交换 | | **内存分配器** | 提供STL兼容的内存分配机制 | 在共享内存中使用容器 | | **原子操作** | 支持boost::atomic保证线程安全 | 多进程并发访问 | ### 安全注意事项 1. **资源泄漏风险** - 必须确保程序退出时调用`remove()`(或在析构函数中处理) - 异常安全:建议使用RAII包装器 2. **访问同步** - 多进程访问需配合互斥锁(如`boost::interprocess::named_mutex`) - 示例: ```cpp // 创建互斥锁 boost::interprocess::named_mutex mutex( boost::interprocess::open_or_create, "PLAYING_ADDRESS_mutex" ); // 写操作加锁 mutex.lock(); // 访问共享内存... mutex.unlock(); ``` 3. **大小限制** - Windows默认限制:系统页面文件大小的80% - Linux限制:`/proc/sys/kernel/shmmax` 定义最大值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值