在前一篇文章中,我们有介绍如何利用Boost.Asio构建线程池。
本文继续谈一下Boost.Asio是如何使用无锁的同步方式解决竞态条件的,以及如何构建一个TCP echo server。
无锁同步
线程池
一个简单的线程池实现如下,在每个 worker 线程中执行io_service
的run()
方法:
1 | class AsioThreadPool |
由于多个线程同时运行事件循环(event loop),所以会导致一个问题:即一个 socket 描述符可能会在多个线程之间共享,容易出现竞态条件(race condition)。譬如说,如果某个 socket 的可读事件很快发生了两次,那么就会出现两个线程同时读同一个 socket 的问题。
无锁的同步方式
要怎样解决前面提到的竞态条件呢?Boost.Asio 提供了io_service::strand
:如果多个 event handler 通过同一个 strand 对象分发 (dispatch),那么这些 event handler 就会保证顺序地执行。
例如,下面的例子使用 strand,所以不需要使用互斥锁保证同步了:
1 | AsioThreadPool pool(4); // 开启 4 个线程 |
多线程 Echo Server
下面的EchoServer
可以在多线程中使用,它使用asio::strand
来解决前面提到的竞态问题:
1 |
|
附录:源码