c++ - 并发调用 ASIO 对象的 API 是否安全?
问题描述
我是 ASIO 的新手,想了解线程安全的工作原理,以便弄清楚在使用 ASIO API 时可以做出哪些假设。
到目前为止我发现了什么:
可以运行多个线程io_service.run()
。
因此,可能会从不同的线程调用诸如 的类中的处理程序socket
,但只能从执行的线程调用io_service.run()
。
让我们假设 asocket
有一些必须防止并发访问的内部状态。
将socket
用 包装其处理程序strand
,这将处理程序的执行序列化。它与在每个处理程序中获取互斥锁的效果基本相同,但性能更好。
但socket
也有公共方法,例如socket.async_write_some()
. 它也可以从不同的线程调用。
假设socket.async_write_some()
访问相同的内部状态,因此需要一些保护机制。
公共方法如何以安全的方式访问内部状态?
可以
strand
用来序列化公共方法的调用吗?post([]{ /* actual implementation of the method goes here */})
在公共方法中调用?除了链之外还使用互斥锁?
调用公共 API 时我可以做出哪些假设?
我可以假设 asocket
保护它的内部状态,即使我从不调用的后台线程调用它io_service.run()
?
如果是这样,是否有一些文档?我宁愿不依赖未记录的实现细节。
解决方案
查看线程安全保证,这些保证与每个类一起记录,但通常也是https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/overview/core/threads.html
这证实了:
问:即使我从不调用 io_service.run() 的后台线程调用它,我是否可以假设套接字保护它的内部状态?
不,你不能假设,因为它没有“保护它的内部状态”,你可能的意思是:它不会同步对它的访问。
此外,从运行处理程序的多个线程进行访问并不意味着它是安全的。您可能需要(隐式或显式)来确保这一点。io_service
strands
推荐阅读
- reactjs - 反应动作创建者和动作类型命名约定?
- c# - 在 C# 的同一个异步线程中运行不同的任务
- reactjs - 在 _document 之外使用 Next.js Head 组件会使页面崩溃
- django - 我想更新待办事项列表但是当我尝试更新它时添加新的待办事项
- sql - 有没有办法可以找到一个不包含访问中另一个字段的值的字段?
- sql - Tableau 中的区分大小写语句
- swiftui - NavigationLink 101:如何将数据从主机发送到辅助视图?
- html - 构建响应式表的推荐方法
- c++ - 如何在 Win32 中使用 DLL 挂钩子类化另一个应用程序控件?
- r - 如何使用 shinydashboardPlus 的轮播实现动态数量的幻灯片?