asio中的锁

asio到底有没有锁

asio是有锁的,所以规避锁的写法还是值得研究的

windows中的锁

先来张截图:
asio中的锁_第1张图片
dispatch_mutex_主要是为了保护定时器队列和完成端口回调的队列。

保护定时器队列

asio中的锁_第2张图片

保护完成端口回调的队列

在PostQueuedCompletionStatus失败时,放入completed_ops_中,以便下一次事件到来,再次尝试从completed_ops_取执行
asio中的锁_第3张图片

windows中 每个线程一个io_context 和 多个线程一个io_context

先来看看 最熟悉的 io_context.run() 的实现:
asio中的锁_第4张图片
只要 do_one函数不返回0,run函数会一直循环下去。run函数实现没有用到锁。再看看do_one函数的实现:
asio中的锁_第5张图片
折叠起来的代码不包含锁,那么只有dispatch_required_ 为1时,才会出现锁竞争:

  1. 定时器添加
  2. completed_ops_不为空,即PostQueuedCompletionStatus函数失败(基本不会)

所以在没有大量高频触发的定时器前提下,windows平台 每个线程一个io_context 和 多个线程一个io_context 性能基本没有区别。

linux中的锁

先来张截图:
asio中的锁_第6张图片
mutex_为了保护内部数据,这个注释给人的第一感觉就是 锁范围明显要比windows要大了。

保护Proactor回调的队列

asio中的锁_第7张图片

linux中 每个线程一个io_context 和 多个线程一个io_context

先来看看 最熟悉的 io_context.run() 的实现:
asio中的锁_第8张图片
只要 do_one函数不返回0,run函数会一直循环下去。首先锁住do_run_one函数,再看看do_one函数的实现:
asio中的锁_第9张图片
简单看一下,折叠的代码里面调用的是epoll_wait。
如果有多个回调operation需要处理则 more_handlers=true,且有多个线程则 one_thread_=false,那么唤醒一个线程且释放锁,让其他线程再去抢剩余的回调operation。
所以Linux平台最好使用 1 io_context per thread 模型 避免锁带来的影响。

你可能感兴趣的:(C/C++,c++,asio)