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 <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
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 <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
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<int*>(region.get_address());
*i1 = 99;
boost::interprocess::mapped_region region2(shdmem, boost::interprocess::read_only);
int *i2 = static_cast<int*>(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 <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream>
int main()
{
boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
int *i = managed_shm.find_or_construct<int>("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 <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <iostream>
int main()
{
boost::interprocess::managed_shared_memory managed_shm(boost::interprocess::open_or_create, "shm", 1024);
int *i = managed_shm.find_or_construct<int>("Integer")();
boost::interprocess::interprocess_mutex *mtx = managed_shm.find_or_construct<boost::interprocess::interprocess_mutex>("mtx")();
mtx->lock();
++(*i);
std::cout << *i << std::endl;
mtx->unlock();
}