Skip to content

Boost.asio 库的多线程模型

参考链接:浅谈 Boost.Asio 的多线程模型 - Boblim - 博客园 (cnblogs.com)

Boost.Asio 有两种支持多线程的方式:

  1. 在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法;
  2. 全局只分配一个io_service,并且让这个io_service在多个线程之间共享,每个线程都调用全局的io_service的run()方法;

每个线程一个 I/O service

这种方式每个线程都持有一个io_service (通常的做法是,让线程数和 CPU 核心数保持一致)。

特点:

  1. 在多核的机器上,这种方案可以充分利用多个 CPU 核心;
  2. 某个 socket 描述符并不会在多个线程之间共享,所以不需要引入同步机制;
  3. 在 event handler 中不能执行阻塞的操作,否则将会阻塞掉io_service所在的线程。

一个 I/O Service 与多个线程

这种方案先分配一个全局io_service,然后开启多个线程,每个线程都调用这个io_service的run()方法。这样,当某个异步事件完成时,io_service就会将相应的 event handler 交给任意一个线程去执行。

然而这种方案在实际使用中,需要注意一些问题:

  1. 在 event handler 中允许执行阻塞的操作 (例如数据库查询操作)。
  2. 线程数可以大于 CPU 核心数,譬如说,如果需要在 event handler 中执行阻塞的操作,为了提高程序的响应速度,这时就需要提高线程的数目。
  3. 由于多个线程同时运行事件循环(event loop),所以会导致一个问题:即一个 socket 描述符可能会在多个线程之间共享,容易出现竞态条件 (race condition)。譬如说,如果某个 socket 的可读事件很快发生了两次,那么就会出现两个线程同时读同一个 socket 的问题 (可以使用strand解决这个问题)。

基于 VitePress 构建