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

文章目录

  • 1 共享内存
    • 1.1 创建共享内存
    • 1.2 将共享内存映射到进程的地址空间
    • 1.3 在共享内存中写入和读取
    • 1.4 删除共享内存
    • 1.5 使用特定于Windows的共享内存

传送门 ==>> 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';
}

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';
}

要使用类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';
}

示例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';
}

要删除共享内存,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';
}

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

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

你可能感兴趣的:(其他,c++,共享内存)