Boost库进程通信

1.Boost.Interprocess和Boost.Asio库

1) Boost.Interprocess库,它包括众多的类,这些类提供了操作系统相关的进程间通讯接口的抽象层。

2)如果同一台计算机不同进程之间通信,虽然也可考虑选择Boost.Asio,但是性能方面不如Boost.Interprocess,因为Boost.Interprocess是使用操作系统的功能优化了同一台计算机不同进程间数据交换。如果不同台计算机进程之间数据交换,则考虑选择Boost.Asio。

2.共享内存

共享内存通常是进程间通讯最快的形式。 它提供一块在应用程序间共享的内存区域。 一个应用能够读数据,另一个应用写数据。

1)boost:interprocess::shared_memory_object类,用于声明一块共享内存

2)boost:interprocess::mapped_region类,用于应用程序映射共享内存到自己的地址空间上

3)为了调整共享内存的大小,truncate() 函数可以被重复调用。

4)通过remove() 函数,可以删除共享内存,传入共享内存的名称即可。

#include  
#include  

int main()
{
	boost::interprocess::shared_memory_object shdmem(boost::interprocess::open_or_create, "Highscore", boost::interprocess::read_write);
	shdmem.truncate(1024);
	boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write);
	std::cout << std::hex << "0x" << region.get_address() << std::endl;
	std::cout << std::dec << region.get_size() << std::endl;
	boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only);
	std::cout << std::hex << "0x" << region2.get_address() << std::endl;
	std::cout << std::dec << region2.get_size() << std::endl;

	system("pause");
} 

boost::interprocess::shared_memory_object 的构造函数需要三个参数。 第一个参数指定共享内存是要创建或打开。 上面的例子实际上是指定了两种方式:用 boost::interprocess::open_or_create 作为参数,共享内存如果存在就将其打开,否则创建之。

假设之前已经创建了共享内存,现打开前面已经创建的共享内存。 为了唯一标识一块共享内存,需要为其指定一个名称,传递给 boost::interprocess::shared_memory_object 构造函数的第二个参数指定了这个名称。

第三个,也就是最后一个参数指示应用程序如何访问共享内存。 例子应用程序能够读写共享内存,这是因为最后的一个参数是 boost::interprocess::read_write。

在创建一个 boost::interprocess::shared_memory_object 类型的对象后,相应的共享内存就在操作系统中建立了。 可是此共享内存区域的大小被初始化为0.为了使用这块区域,需要调用 truncate() 函数,以字节为单位传递请求的共享内存的大小。 对于上面的例子,共享内存提供了1,024字节的空间。

请注意,truncate() 函数只能在共享内存以 boost::interprocess::read_write 方式打开时调用。 如果不是以此方式打开,将抛出 boost::interprocess::interprocess_exception 异常。

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

4)利用共享内存写入并读取一个数字

同一个共享内存(名为"Highscore"),被映射到进程的地址空间两次。通过变量region,99被写到共享内存的起始地址,然后通过变量region2,访问共享内存的同一地址,所以可以输出数字99。

实际上在同一个应用程序中,将同一块共享内存映射到程序的地址空间两次,没有多大的意义。实际开发中,都是两个或多个应用程序,映射同一块共享内存到各自的地址空间。

#include  
#include  
#include  

int main() 
{ 
  boost::interprocess::shared_memory_object shdmem(boost::interprocess::open_or_create, "Highscore", boost::interprocess::read_write); 
  shdmem.truncate(1024); 
  boost::interprocess::mapped_region region(shdmem, boost::interprocess::read_write); 
  int *i1 = static_cast(region.get_address()); 
  *i1 = 99; 
  boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only); 
  int *i2 = static_cast(region2.get_address()); 
  std::cout << *i2 << std::endl; 
}

5)remove()

windows系统下,使用boost::interprocess::shared_memory_object创建的共享内存,在不用时必须用remove函数删除,如果不删除,即使重启系统,该共享内存还是存在的,因为windows下将共享内存存储在持久化的文件上,此文件在系统重启后还是存在的。

windows下可以使用专门为windows设计的类,该方法创建的共享内存,会在最后一个使用它的进程退出后自动删除。

boost::interprocess::windows_shared_memory shdmem(boost::interprocess::open_or_create, "Highscore", boost::interprocess::read_write, 1024); 

3.共享内存的同步

1)Boost::Interprocess提供两种同步对象,匿名对象和命名对象(boost::interprocess::named_mutex)。

匿名对象存储在共享内存上,所以所有应用程序都能访问,命名对象由操作系统管理,不存储在共享内存上,应用程序可以通过名称访问它。

//利用命名互斥对象实现互斥
#include  
#include  
#include  

int main() 
{ 
  boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024); 
  int *i = managed_shm.find_or_construct("Integer")(); 
  boost::interprocess::named_mutex named_mtx(boost::interprocess::open_or_create, "mtx"); 
  named_mtx.lock(); 
  ++(*i); 
  std::cout << *i << std::endl; 
  named_mtx.unlock(); 
} 
//利用匿名互斥对象实现同步,因为匿名对象在共享内存上,所有可以直接用find_or_construct()函数
#include  
#include  
#include  

int main() 
{ 
  boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024); 
  int *i = managed_shm.find_or_construct("Integer")(); 
  boost::interprocess::interprocess_mutex *mtx = managed_shm.find_or_construct("mtx")(); 
  mtx->lock(); 
  ++(*i); 
  std::cout << *i << std::endl; 
  mtx->unlock(); 
} 

参考:Boost中文网 第八章 进程间通信

你可能感兴趣的:(C++,Boost学习笔记,Boost进程通信,共享内存,进程同步)