Boost.Interprocess 官方文档学习笔记

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

促进Interprocess简化了常见进程间通信和同步机制的使用,并提供了多种机制:

  • 共享内存。
  • 内存映射文件。
  • 信号量、互斥量、条件变量和可升级的互斥量类型,以将它们放置在共享内存和内存映射文件中。
  • 这些同步对象的命名版本,类似于UNIX/Windows的sem_open/CreateSemaphore API。
  • 文件锁定。
  • 相对指针。
  • 消息队列。

boost::interprocess::shared_memory_object

boost::interprocess::shared_memory_object对象用来表示共享内存,头文件为<boost/interprocess/shared_memory_object.hpp>, 创建共享内存的示例

#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>

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::open_or_create表示如果共享内存已经存在,将打开共享内存;如果不存在,将创建共享内存。

打开现有共享内存假定它以前已创建。要唯一标识共享内存,需要指定一个名称。该名称由传递给的构造函数的第二个参数指定。

第三个参数确定进程如何访问共享内存。

创建boost::interprocess::shared_memory_object类型的对象后,操作系统中将存在相应的共享内存块。此内存区域的大小最初为0。要使用该区域,请调用truncate(),以字节为单位传入共享内存的大小。在示例中,共享内存提供1024字节的空间。只有使用boost::interprocess::read_ write打开共享内存时,才能调用truncate()。否则,将引发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区域将其他对象映射到进程的地址空间。

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>

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::shared_memory_object,第二个参数表示读写权限。

创建两个boost::interprocess::mapped_region类型的对象。名为Boost的共享内存被两次映射到进程的地址空间。使用成员函数get_address() 和get_size()将映射内存区域的地址和大小写入标准输出。在这两种情况下,get_size()都返回1024,但对于每个对象,get_address() 的返回值是不同的。

#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>

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

使用映射的内存区域写入和读取数字。region将数字99写入共享内存的开头。region2然后读取共享内存中的相同位置,并将数字写入标准输出流。尽管region和region2代表进程中不同的内存区域,如前一个示例中get_address()的返回值所示,程序都会打印99,因为这两个内存区域访问相同的底层共享内存。

#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>

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(),该函数将要删除的共享内存的名称作为参数。

Boost.Interprocess通过一个名为boost::interprocess::remove_shared_memory_on_destroy的类部分支持RAII习惯用法。其构造函数需要现有共享内存的名称。如果销毁此类的对象,则会在析构函数中自动删除共享内存。

如果从不调用remove(),则即使程序终止,共享内存也会继续存在。是否自动删除共享内存取决于底层操作系统。Windows和许多Unix操作系统(包括Linux)在系统重新启动后会自动删除共享内存。

Windows提供了一种特殊的共享内存,一旦使用它的最后一个进程终止,它就会自动删除。访问boost::interprocess::windows_shared_memory类,该类头文件为boost/interprocess/windows_shared_memory.hpp

#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>

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::managed_shared_memory

boost::interprocess::shared_memory_object虽然可用于创建和管理共享内存。实际上,这个类很少使用,因为它需要程序从共享内存读写单个字节。C++风格倾向于创建类的对象,并隐藏数据存储在内存中的位置和方式的细节。

Boost.Interprocess提供boost::interprocess::managed_shared_memory来支持托管共享内存。此类允许您实例化内存位于共享内存中的对象,使这些对象自动可供访问相同共享内存的任何程序使用。头文件是:boost/interprocess/managed_shared_memory.hpp

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  int *i = managed_shm.construct<int>("Integer")(99);
  std::cout << *i << '\n';
  std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
  if (p.first)
    std::cout << *p.first << '\n';
}

打开大小为1024字节的名为Boost的共享内存。如果共享内存不存在,它将自动创建。

在常规共享内存中,直接访问单个字节以读取或写入数据。托管共享内存使用诸如construct()之类的成员函数,该函数需要一个类型作为模板参数(在示例中,int)。成员函数需要一个名称来表示在托管共享内存中创建的对象。示例使用名称Integer。

由于construct()返回代理对象,因此可以向其传递参数以初始化创建的对象。该语法看起来像是对构造函数的调用。这确保了可以在托管共享内存中创建和初始化对象。

要访问托管共享内存中的特定对象,请使用成员函数find()。通过传递要查找的对象的名称,find()返回指向该对象的指针,如果找不到具有给定名称的对象,则返回0。

如示例所示,find()返回std::pair类型的对象。指向对象的指针first作为成员变量提供。示例显示了的内容。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  int *i = managed_shm.construct<int>("Integer")[10](99);
  std::cout << *i << '\n';
  std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
  if (p.first)
  {
    std::cout << *p.first << '\n';
    std::cout << p.second << '\n';
  }
}

在示例中,通过在调用construct()后提供用方括号括起来的值10,创建了一个包含10个int类型元素的数组。使用成员变量second将相同的10写入标准输出流。由于这个成员变量,您可以判断find()返回的对象是单个对象还是数组。对于前者,second为1,而对于后者,second为数组中的元素数。

请注意,数组中的所有十个元素都用值99初始化。如果要使用不同的值初始化元素,请传递迭代器。

如果托管共享内存中已存在具有给定名称的对象,则construct()将失败。在这种情况下,construct()返回0,不进行初始化。要使用现有对象,请使用成员函数find_or_construct(),该函数返回指向现有对象的指针或创建新对象。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  try
  {
    shared_memory_object::remove("Boost");
    managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
    int *i = managed_shm.construct<int>("Integer")[4096](99);
  }
  catch (boost::interprocess::bad_alloc &ex)
  {
    std::cerr << ex.what() << '\n';
  }
}

还有其他一些情况会导致construct()失败。示例尝试创建一个包含4096个元素的int类型数组。然而,托管共享内存仅包含1024个字节。这会导致引发boost::interprocess::bad_alloc类型的异常。

在托管共享内存中创建对象后,可以使用成员函数destroy()将其删除。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  int *i = managed_shm.find_or_construct<int>("Integer")(99);
  std::cout << *i << '\n';
  managed_shm.destroy<int>("Integer");
  std::pair<int*, std::size_t> p = managed_shm.find<int>("Integer");
  std::cout << p.first << '\n';
}

在示例中,要删除的对象的名称作为destroy()的唯一参数传递。可以检查bool类型的返回值,以验证是否已成功找到并删除给定对象。由于如果找到对象,将始终删除该对象,因此返回值false表示未找到具有给定名称的对象。

成员函数destroy_ptr()可用于传递指向托管共享内存中对象的指针。它还可用于删除阵列。

由于托管共享内存使在进程之间共享对象变得相当容易,因此使用标准库中的容器似乎也很自然。但是,这些容器使用new分配内存。为了在托管共享内存中使用这些容器,需要告诉它们在共享内存中分配内存。

标准库的许多实现都不够灵活,无法将std::string或std::list等容器与Boost一起使用。

要允许开发人员使用标准库中的容器,请boost::interprocess名称空间中的实现。例如,boost::interprocess::string 的行为与对应的std::string完全相同,只是字符串可以安全地存储在托管共享内存中。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  typedef allocator<char,
    managed_shared_memory::segment_manager> CharAllocator;
  typedef basic_string<char, std::char_traits<char>, CharAllocator> string;
  string *s = managed_shm.find_or_construct<string>("String")("Hello!",
    managed_shm.get_segment_manager());
  s->insert(5, ", world");
  std::cout << *s << '\n';
}

要创建一个字符串,该字符串将在其所在的同一托管共享内存中分配内存,必须定义相应的类型。新字符串类型必须使用Boost.Interprocess提供的分配器,而不是标准提供的默认分配器。

为此,Boost.Interprocess提供boost::interprocess::allocator类,该类在boost/interprocess/allocators/allocator.hpp中定义。通过此类,可以创建一个分配器,该分配器在内部使用托管共享内存的段管理器。段管理器负责管理托管共享内存块中的内存。使用新创建的分配器,可以为字符串定义相应的类型。如上所述,请使用boost::interprocess::basic_string 而不是std::basic_string。

新类型string 基于boost::interprocess::basic_string,并通过其分配器访问段管理器。要让通过调用find_or_construct()创建的字符串的特定实例知道它应该访问哪个段管理器,请将指向相应段管理器的指针作为第二个参数传递给构造函数。

Boost.Interprocess 为标准库中的许多其他容器提供了实现。例如,boost::interprocess::vector和boost::interprocess::map,头文件分别为:boost/interprocess/containers/vector.hpp 和boost/interprocess/containers/map.hpp

请注意,Boost.Container容器支持Boost.Interprocess的要求,可放入共享内存。可以使用它们代替Boost.Interprocess中的容器。

每当从不同进程访问相同的托管共享内存时,创建、查找和销毁对象等操作都会自动同步。如果两个程序试图在托管共享内存中创建具有不同名称的对象,则会相应地序列化访问。要一次执行多个操作而不被来自不同进程的操作中断,请使用成员函数atomic_func()

#include <boost/interprocess/managed_shared_memory.hpp>
#include <functional>
#include <iostream>

using namespace boost::interprocess;

void construct_objects(managed_shared_memory &managed_shm)
{
  managed_shm.construct<int>("Integer")(99);
  managed_shm.construct<float>("Float")(3.14);
}

int main()
{
  shared_memory_object::remove("Boost");
  managed_shared_memory managed_shm{open_or_create, "Boost", 1024};
  auto atomic_construct = std::bind(construct_objects,
    std::ref(managed_shm));
  managed_shm.atomic_func(atomic_construct);
  std::cout << *managed_shm.find<int>("Integer").first << '\n';
  std::cout << *managed_shm.find<float>("Float").first << '\n';
}

atomic_func()接受一个不接受参数且没有返回值的函数作为其单个参数。传递的函数将以确保独占访问托管共享内存的方式进行调用。但是,只有当访问托管共享内存的所有其他进程也使用atomic_func()时,才能确保独占访问。如果另一个进程有一个指向托管共享内存中某个对象的指针,它可以使用其指针访问和修改该对象。

Boost.Interprocess还可用于同步对象访问。因为Boost.Interprocess不知道谁可以在特定时间访问单个对象,需要显式处理同步。以下部分介绍为同步提供的类。

共享内存的同步

Boost.Interprocess允许多个进程同时使用共享内存。因为根据定义,共享内存在进程之间是共享的,所以Boost.Interprocess需要支持某种同步。

进程间的同步与Boost.Thread或者标准库中提供的std::mutex这类线程间同步类似。但线程间同步的类只能用于同步同一进程中的线程;它们不支持不同进程的同步。然而,由于两种情况下的挑战是相同的,因此概念也是相同的。

虽然多线程应用程序中的同步对象(如互斥量和条件变量)位于相同的地址空间中,因此所有线程都可以使用,但共享内存的挑战在于独立进程需要共享这些对象。例如,如果一个进程创建了互斥体,则需要从其他进程访问互斥体。

Boost.Interprocess 提供了两种类型的同步对象:匿名对象直接存储在共享内存中,这样所有进程都可以自动使用它们。命名对象由操作系统管理,不存储在共享内存中,可以通过名称从程序中引用。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  managed_shared_memory managed_shm{open_or_create, "shm", 1024};
  int *i = managed_shm.find_or_construct<int>("Integer")();
  named_mutex named_mtx{open_or_create, "mtx"};
  named_mtx.lock();
  ++(*i);
  std::cout << *i << '\n';
  named_mtx.unlock();
}

使用boost::interprocess::named_mutex类创建并使用命名互斥体,该类头文件在:boost/interprocess/sync/named_mutex.hpp。

boost::interprocess::named_mutex的构造函数需要一个参数,指定是创建还是打开互斥体,以及互斥体的名称。每个知道名称的进程都可以打开相同的互斥锁。要访问共享内存中的数据,程序需要通过调用成员函数lock()获得互斥体的所有权。因为互斥锁一次只能由一个进程拥有,所以另一个进程可能需要等待,直到unlock()释放互斥锁。一旦进程获得互斥体的所有权,它就可以独占访问互斥体保护的资源。在示例中,资源是一个int类型的变量,该变量递增并写入标准输出流。

如果示例程序多次启动,则每个实例将打印一个值,该值与之前的值相比增加1。由于互斥锁,对共享内存的访问和变量本身在不同进程之间是同步的。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <iostream>

using namespace boost::interprocess;

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

使用boost::interprocess::interprocess_mutex类型的匿名互斥体,该互斥体在头文件boost/interprocess/sync/interprocess_mutex.hpp中定义。为了让所有进程都可以访问互斥体,互斥体存储在共享内存中。

这个示例行为与前一个完全相同。唯一的区别是互斥锁,它现在直接存储在共享内存中。这可以通过boost::interprocess::managed_shared_memory类中的成员函数construct() 或 find_or_construct()完成。

除了lock(),boost::interprocess::named_mutex 和boost::interprocess::interprocess_mutex都提供成员函数try_ock()和timed_ock()。它们的行为与标准库和Boost中的对应项完全相同。线如果需要递归互斥锁,请Boost.Interprocess提供两个类:boost::interprocess::named_recursive_mutex 和boost::interprocess::interprocess_recursive_mutex

互斥锁保证对共享资源的独占访问,而条件变量控制谁在什么时候拥有独占访问权。通常,Boost.Interprocess提供的条件变量的工作方式与C++11标准库和Boost.Thread提供的类似。它们有相似的接口,这使得这些库的用户在使用Boost.Interprocess的这些变量时立即感到宾至如归。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/named_mutex.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  managed_shared_memory managed_shm{open_or_create, "shm", 1024};
  int *i = managed_shm.find_or_construct<int>("Integer")(0);
  named_mutex named_mtx{open_or_create, "mtx"};
  named_condition named_cnd{open_or_create, "cnd"};
  scoped_lock<named_mutex> lock{named_mtx};
  while (*i < 10)
  {
    if (*i % 2 == 0)
    {
      ++(*i);
      named_cnd.notify_all();
      named_cnd.wait(lock);
    }
    else
    {
      std::cout << *i << std::endl;
      ++(*i);
      named_cnd.notify_all();
      named_cnd.wait(lock);
    }
  }
  named_cnd.notify_all();
  shared_memory_object::remove("shm");
  named_mutex::remove("mtx");
  named_condition::remove("cnd");
}

示例使用boost::interprocess::named_condition类型的条件变量,该变量在boost/interprocess/sync/named_condition.hpp中定义。因为它是一个命名变量,所以不需要存储在共享内存中。

应用程序使用while循环递增int类型的变量,该变量存储在共享内存中。尽管变量在循环的每次迭代中都会递增,但它只会在每一次迭代中写入到标准输出流中,即只会写入奇数。

每次变量递增1,就会调用named_cnd条件变量的成员函数wait(), 名为lock的互斥体传递给wait成员函数。这是基于RAII的习惯用法,即在构造函数中获得互斥体的所有权,然后在析构函数中释放互斥体。

锁在while循环之前创建,并在整个程序执行过程中拥有互斥锁的所有权。但是,如果作为参数传递给wait(),则会自动释放锁。

条件变量用于等待指示等待结束的信号。同步由成员函数wait()和notify_all()控制。当程序调用wait()时,相应互斥锁的所有权将被释放。然后,程序将等待,直到其它进程对同一条件变量调用notify_all()。

在while循环中,变量i从0增加到1后,程序通过调用wait()等待信号。为了触发信号,需要启动程序的第二个实例。

第二个实例尝试在进入while循环之前获取同一互斥体的所有权。这会成功,因为第一个实例通过调用wait()释放互斥体。因为变量已递增一次,所以第二个实例执行if表达式的else分支,并将当前值写入标准输出流。然后该值增加1。

现在,第二个实例也调用wait()。但是,在此之前,它会调用notify_all(),以确保这两个实例正确协作。第一个实例收到通知并再次尝试获取互斥锁的所有权,该互斥锁仍由第二个实例拥有。但是,由于第二个实例在调用notify_all()之后立即调用wait(),这会自动释放所有权,因此第一个实例将在此时获得所有权。

这两个实例交替使用,递增共享内存中的变量。但是,只有一个实例将值写入标准输出流。一旦变量达到值10,while循环就完成了。为了避免另一个实例永远等待信号,在循环后再次调用notify_all()。在终止之前,共享内存、互斥锁和条件变量将被销毁。

正如有两种类型的互斥体(必须存储在共享内存中的匿名类型和命名类型)一样,也有两种类型的条件变量。下面示例使用匿名条件变量重写了前面的示例。

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <iostream>

using namespace boost::interprocess;

int main()
{
  managed_shared_memory managed_shm{open_or_create, "shm", 1024};
  int *i = managed_shm.find_or_construct<int>("Integer")(0);
  interprocess_mutex *mtx =
    managed_shm.find_or_construct<interprocess_mutex>("mtx")();
  interprocess_condition *cnd =
    managed_shm.find_or_construct<interprocess_condition>("cnd")();
  scoped_lock<interprocess_mutex> lock{*mtx};
  while (*i < 10)
  {
    if (*i % 2 == 0)
    {
      ++(*i);
      cnd->notify_all();
      cnd->wait(lock);
    }
    else
    {
      std::cout << *i << std::endl;
      ++(*i);
      cnd->notify_all();
      cnd->wait(lock);
    }
  }
  cnd->notify_all();
  shared_memory_object::remove("shm");
}

这个示例的工作方式与前一个完全相同,还需要启动两次才能将int变量递增十倍。

除了互斥量和条件变量之外,Boost.Interprocess还支持信号量和文件锁。信号量与条件变量相似,只是它们不区分两种状态;相反,它们基于计数器。文件锁的行为类似于互斥锁,只是它们用于硬盘上的文件,而不是内存中的对象。

与C++11标准库和Boost.Thread区分不同类型的互斥锁和锁一样,Boost.Interprocess提供多个互斥锁和锁。例如,互斥锁可以是独占的或非独占的。如果多个进程需要同时读取数据,这会很有帮助,因为只有写入数据时才需要专用互斥锁。不同的锁类可用于将RAII习惯用法应用于各个互斥锁。

除非使用匿名同步对象,否则名称应唯一。尽管互斥量和条件变量是基于不同类的对象,但对于Boost包装的依赖于操作系统的接口,这可能不一定成立。进程间。在Windows上,相同的操作系统函数用于互斥量和条件变量。如果两个对象(每种类型一个)使用相同的名称,程序将无法在Windows上正常运行。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
THE BOOST C++ LIBRARIES是一份自己编译的chm格式文档,描述了如何使用boost类库,目录如下: Front page Chapter 1: Introduction 1.1 C++ and Boost 1.2 Development Process 1.3 Installation 1.4 Overview Chapter 2: Smart Pointers 2.1 General 2.2 RAII 2.3 Scoped Pointer 2.4 Scoped Array 2.5 Shared Pointer 2.6 Shared Array 2.7 Weak Pointer 2.8 Intrusive Pointer 2.9 Pointer Container 2.10 Exercises Chapter 3: Function Objects 3.1 General 3.2 Boost.Bind 3.3 Boost.Ref 3.4 Boost.Function 3.5 Boost.Lambda 3.6 Exercises Chapter 4: Event Handling 4.1 General 4.2 Signals 4.3 Connections 4.4 Exercises Chapter 5: String Handling 5.1 General 5.2 Locales 5.3 Boost.StringAlgorithms 5.4 Boost.Regex 5.5 Boost.Tokenizer 5.6 Boost.Format 5.7 Exercises Chapter 6: Multithreading 6.1 General 6.2 Thread Management 6.3 Synchronization 6.4 Thread Local Storage 6.5 Exercises Chapter 7: Asynchronous Input and Output 7.1 General 7.2 I/O Services and I/O Objects 7.3 Scalability and Multithreading 7.4 Network Programming 7.5 Developing Boost.Asio Extensions 7.6 Exercises Chapter 8: Interprocess Communication 8.1 General 8.2 Shared Memory 8.3 Managed Shared Memory 8.4 Synchronization 8.5 Exercises Chapter 9: Filesystem 9.1 General 9.2 Paths 9.3 Files and Directories 9.4 File Streams 9.5 Exercises Chapter 10: Date and Time 10.1 General 10.2 Calendar Dates 10.3 Location-independent Times 10.4 Location-dependent Times 10.5 Formatted Input and Output 10.6 Exercises Chapter 11: Serialization 11.1 General 11.2 Archive 11.3 Pointers and references 11.4 Serialization of class hierarchy objects 11.5 Wrapper functions for optimization 11.6 Exercises Chapter 12: Parser 12.1 General 12.2 Extended Backus-Naur Form 12.3 Grammar 12.4 Actions 12.5 Exercises Chapter 13: Containers 13.1 General 13.2 Boost.Array 13.3 Boost.Unordered 13.4 Boost.MultiIndex 13.5 Boost.Bimap 13.6 Exercises Chapter 14: Data Structures 14.1 General 14.2 Boost.Tuple 14.3 Boost.Any 14.4 Boost.Variant 14.5 Exercises Chapter 15: Error Handling 15.1 General 15.2 Boost.System 15.3 Boost.Exception Chapter 16: Cast Operators

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值