Boost IPC Persistence Of Interprocess Mechanisms 例子

时间:2022-09-09 00:00:46

下面这一段摘抄自 Boost 1_55_0 的文档,显然标注了 每一个的生命期。

 

One of the biggest issues with interprocess communication mechanisms is the lifetime of the interprocess communication mechanism. It's important to know when an interprocess communication mechanism disappears from the system. In Boost.Interprocess, we can have 3 types of persistence:

  • Process-persistence: The mechanism lasts until all the processes that have opened the mechanism close it, exit or crash.
  • Kernel-persistence: The mechanism exists until the kernel of the operating system reboots or the mechanism is explicitly deleted.
  • Filesystem-persistence: The mechanism exists until the mechanism is explicitly deleted.

Some native POSIX and Windows IPC mechanisms have different persistence so it's difficult to achieve portability between Windows and POSIX native mechanisms. Boost.Interprocess classes have the following persistence:

Boost IPC Persistence Of Interprocess Mechanisms 例子

As you can see, Boost.Interprocess defines some mechanisms with "Kernel or Filesystem" persistence. This is because POSIX allows this possibility to native interprocess communication implementations. One could, for example, implement shared memory using memory mapped files and obtain filesystem persistence (for example, there is no proper known way to emulate kernel persistence with a user library for Windows shared memory using native shared memory, or process persistence for POSIX shared memory, so the only portable way is to define "Kernel or Filesystem" persistence).

 

最好的是下面这一个简单的example。

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

在主进程中创建另一个进程,这个进程来验证之前的共享内存是否被初始化为1。 因为我们的shared memory的生命期是 Kernel 或者是filesystem,所以进程2 是可以验证的。 值得注意一点的是这里的remover,他是一个栈对象,所以每次都销毁,显式调用了 remove,如果去掉这个remover,那么只需要执行一次,以后每次输入这个显式内存都是存在的。因为他的生命期是 kernel 或者filesystem。 所以这里的remover 至关重要!