asio到底有没有锁
asio是有锁的,所以规避锁的写法还是值得研究的
windows中的锁
先来张截图:
dispatch_mutex_主要是为了保护定时器队列和完成端口回调的队列。
保护定时器队列
保护完成端口回调的队列
在PostQueuedCompletionStatus失败时,放入completed_ops_中,以便下一次事件到来,再次尝试从completed_ops_取执行
windows中 每个线程一个io_context 和 多个线程一个io_context
先来看看 最熟悉的 io_context.run() 的实现:
只要 do_one函数不返回0,run函数会一直循环下去。run函数实现没有用到锁。再看看do_one函数的实现:
折叠起来的代码不包含锁,那么只有dispatch_required_ 为1时,才会出现锁竞争:
- 定时器添加
- completed_ops_不为空,即PostQueuedCompletionStatus函数失败(基本不会)
所以在没有大量高频触发的定时器前提下,windows平台 每个线程一个io_context 和 多个线程一个io_context 性能基本没有区别。
linux中的锁
先来张截图:
mutex_为了保护内部数据,这个注释给人的第一感觉就是 锁范围明显要比windows要大了。
保护Proactor回调的队列
linux中 每个线程一个io_context 和 多个线程一个io_context
先来看看 最熟悉的 io_context.run() 的实现:
只要 do_one函数不返回0,run函数会一直循环下去。首先锁住do_run_one函数,再看看do_one函数的实现:
简单看一下,折叠的代码里面调用的是epoll_wait。
如果有多个回调operation需要处理则 more_handlers=true,且有多个线程则 one_thread_=false,那么唤醒一个线程且释放锁,让其他线程再去抢剩余的回调operation。
所以Linux平台最好使用 1 io_context per thread 模型 避免锁带来的影响。