Boost.asio 库的多线程模型
参考链接:浅谈 Boost.Asio 的多线程模型 - Boblim - 博客园 (cnblogs.com)
Boost.Asio 有两种支持多线程的方式:
- 在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法;
- 全局只分配一个io_service,并且让这个io_service在多个线程之间共享,每个线程都调用全局的io_service的run()方法;
每个线程一个 I/O service
这种方式每个线程都持有一个io_service (通常的做法是,让线程数和 CPU 核心数保持一致)。
特点:
- 在多核的机器上,这种方案可以充分利用多个 CPU 核心;
- 某个 socket 描述符并不会在多个线程之间共享,所以不需要引入同步机制;
- 在 event handler 中不能执行阻塞的操作,否则将会阻塞掉io_service所在的线程。
一个 I/O Service 与多个线程
这种方案先分配一个全局io_service,然后开启多个线程,每个线程都调用这个io_service的run()方法。这样,当某个异步事件完成时,io_service就会将相应的 event handler 交给任意一个线程去执行。
然而这种方案在实际使用中,需要注意一些问题:
- 在 event handler 中允许执行阻塞的操作 (例如数据库查询操作)。
- 线程数可以大于 CPU 核心数,譬如说,如果需要在 event handler 中执行阻塞的操作,为了提高程序的响应速度,这时就需要提高线程的数目。
- 由于多个线程同时运行事件循环(event loop),所以会导致一个问题:即一个 socket 描述符可能会在多个线程之间共享,容易出现竞态条件 (race condition)。譬如说,如果某个 socket 的可读事件很快发生了两次,那么就会出现两个线程同时读同一个 socket 的问题 (可以使用strand解决这个问题)。