• 【Boost C++ 库】共享内存详解


    传送门 ==>> AutoSAR实战系列300讲总目录

    1 共享内存

    共享内存通常是interprocess 通信的最快的方式。它提供了一个在进程process之间共享的内存区域。一个process可以将数据写入该区域,另一个process可以读取它。

    在boost.interprocess中,该类boost::interprocess::shared_memory_object用于表示共享内存。包含头文件boost/interprocess/shared_memory_object.hpp以使用此类。

    1.1 创建共享内存

    Example 33.1. 创建共享内存

    #include 
    #include 
    
    using namespace boost::interprocess;
    
    int main()
    {
      shared_memory_object shdmem{open_or_create, "Boost", read_write};
      shdmem.truncate(1024);
      std::cout << shdmem.get_name() << '\n';
      offset_t size;
      if (shdmem.get_size(size))
        std::cout << size << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    boost::interprocess::shared_memory_object通过三个参数使用构造函数。

    • 第一个参数指定应创建还是仅仅是打开共享内存。示例33.1包含了这两种情况,也就是说boost::interprocess::open_or_create:如果已经存在共享内存则打开共享内存,如果不存在共享内存创建共享内存。打开共享内存说明该共享内存是之前创建的。
      要唯一识别共享内存,请分配一个名称。

    • 第二个参数指定boost::interprocess::shared_memory_object的名字。

    • 第三个参数说明进程如何访问共享内存。在示例33.1中boost::interprocess::read_write:说明该进程对共享内存具有读写访问权限。

    创建boost::interprocess::shared_memory_object类型对象后,操作系统中将存在相应的共享内存块。该内存区域的大小最初为0。要使用该区域,调用truncate(),传递参数明白了共享内存的大小(以字节为单位)。在示例33.1中,共享内存提供了1,024个字节空间。truncate()只有在以boost::interprocess::read_write方式打开共享内存的情况下才能调用。如果没有,则抛出了异常:boost::interprocess::interprocess_exception。truncate()可以重复调用以调整共享内存的大小。

    创建共享内存后,成员函数get_name()和get_size()可以用来查询共享内存的名称和大小。

    由于共享内存用于在不同进程之间交换数据,因此每个进程都需要将共享存储器映射到其地址空间中。类boost::interprocess::mapped_region用于执行此操作。即访问共享内存需要两个(boost::interprocess::shared_memory_object和boost::interprocess::mapped_region)。这样做是为了使类boost::interprocess::mapped_region也可以用于将其他对象映射到进程的地址空间中。

    1.2 将共享内存映射到进程的地址空间

    Example 33.2 将共享内存映射到进程的地址空间

    #include 
    #include 
    #include 
    
    using namespace boost::interprocess;
    
    int main()
    {
      shared_memory_object shdmem{open_or_create, "Boost", read_write};
      shdmem.truncate(1024);
      mapped_region region{shdmem, read_write};
      std::cout << std::hex << region.get_address() << '\n';
      std::cout << std::dec << region.get_size() << '\n';
      mapped_region region2{shdmem, read_only};
      std::cout << std::hex << region2.get_address() << '\n';
      std::cout << std::dec << region2.get_size() << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    要使用类boost::interprocess::mapped_region,请包括标头文件boost/interprocess/mapped_region.hpp
    boost::interprocess::mapped_region类的构造函数的第一个参数是boost::interprocess::shared_memory_object类的对象;第二个参数确定对内存区域的访问是仅读取还是读写。

    例 33.2创建了两个类型为 boost::interprocess::mapped_region的对象。名为Boost的共享内存被映射到进程的地址空间。mapped_region成员函数get_address()和get_size()获取映射的内存区域的地址和大小。get_size()在两种情况下返回1024,但是get_address()返回值不同。

    1.3 在共享内存中写入和读取

    Example 33.3. 在共享内存中写入和读取

    #include 
    #include 
    #include 
    
    using namespace boost::interprocess;
    
    int main()
    {
      shared_memory_object shdmem{open_or_create, "Boost", read_write};
      shdmem.truncate(1024);
      mapped_region region{shdmem, read_write};
      int *i1 = static_cast<int*>(region.get_address());
      *i1 = 99;
      mapped_region region2{shdmem, read_only};
      int *i2 = static_cast<int*>(region2.get_address());
      std::cout << *i2 << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    示例33.3使用映射的内存区域写和读取一个数字。region将数字99写入共享内存的开头。然后,region2在共享内存中读取相同的位置,并将数字写入标准输出流。即使regionregion2表示进程中的不同内存区域,如上一个示例中的get_address()返回值所示,该程序也会打印99,因为两个内存区域都可以访问相同的基础共享内存

    1.4 删除共享内存

    Example 33.4. 删除共享内存

    #include 
    #include 
    
    using namespace boost::interprocess;
    
    int main()
    {
      bool removed = shared_memory_object::remove("Boost");
      std::cout << std::boolalpha << removed << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    要删除共享内存,boost::interprocess::shared_memory_object提供静态成员函数remove(),该函数以要删除的共享内存的名称为参数(请参见示例33.4)。

    如果remove()从未调用,即使程序终止,共享内存也会继续存在。共享内存是否自动删除取决于基础操作系统。一旦重新启动系统,Windows和许多UNIX操作系统(包括Linux)将自动删除共享内存。

    Windows提供了一种特殊的共享内存,一旦使用它的最后一个进程终止,该内存将自动删除。可以在boost/interprocess/windows_shared_memory.hpp访问boost::interprocess::windows_shared_memory类,使用这种共享内存,请参见示例33.5。

    1.5 使用特定于Windows的共享内存

    Example 33.5. 使用特定于Windows的共享内存

    #include 
    #include 
    #include 
    
    using namespace boost::interprocess;
    
    int main()
    {
      windows_shared_memory shdmem{open_or_create, "Boost", read_write, 1024};
      mapped_region region{shdmem, read_write};
      int *i1 = static_cast<int*>(region.get_address());
      *i1 = 99;
      mapped_region region2{shdmem, read_only};
      int *i2 = static_cast<int*>(region2.get_address());
      std::cout << *i2 << '\n';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    boost::interprocess::windows_shared_memory不提供成员函数truncate()。相反,需要将共享内存的大小作为第四个参数传递给这个类的构造函数。

    类boost::interprocess::windows_shared_memory只能在Windows上使用,不可移植。

  • 相关阅读:
    pytorch-实现猴痘识别
    通过IP地址如何防范钓鱼网站诈骗?
    Alibaba Cloud Linux 3安装Docker
    (十)Python网络编程
    array enum 的准替代方案(改进版)
    华为云云耀云服务器L实例评测|使用Benchmark工具对云耀云服务器Elasticsearch的性能测试
    视频智能分析平台智能边缘分析一体机安防监控平台打手机检测算法工作原理介绍
    【热门话题】前端框架发展史
    5、Redis的发布和订阅
    VUE面试题总结2
  • 原文地址:https://blog.csdn.net/huihuige092/article/details/126467256