我是 ASIO 新手,喜欢了解线程安全的工作原理,这样我就可以弄清楚在使用 ASIO API 时可以做出哪些假设。
到目前为止我发现了什么:
多个线程可以运行io_service.run()
。
因此,可能会调用 socket
等类中的处理程序
来自不同的线程,但仅来自执行 io_service.run()
的线程。
假设socket
有一些必须受到保护的内部状态
来自并发访问。
socket
将用 strand
包装其处理程序,该链将执行序列化
的处理程序。它与在每个中获取互斥锁具有本质上相同的效果
处理程序,但性能更好。
但是socket
也有公共(public)方法,例如socket.async_write_some()
。它
也可能从不同的线程调用。
假设 socket.async_write_some()
访问相同的内部状态,
所以需要一些保护机制。
公共(public)方法如何安全地访问内部状态?
可以使用
strand
来序列化公共(public)方法的调用吗?在公共(public)方法中调用
post([]{/* 方法的实际实现在此处 */})
?除了链之外还使用互斥锁吗?
调用公共(public) API 时我可以做出哪些假设?
我是否可以假设 socket
会保护其内部状态,即使我从不调用 io_service.run()
的后台线程调用它?
如果是这样,有相关文档吗?我宁愿不依赖于未记录的实现细节。
最佳答案
查看线程安全保证,这些保证随每个类一起记录,但也一般 https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/overview/core/threads.html
这证实了:
Q. Can I assume that a socket protects it's internal state, even if I invoke it from a background thread that does not invoke io_service.run()?
不,您不能这样认为,因为它不会“保护其内部状态”,就像您可能的意思一样:它不会同步对其的访问。
此外,从运行 io_service
处理程序的多个线程进行访问并不意味着它是安全的。您可能需要strand
(隐式或显式)来确保这一点。
关于c++ - 同时调用 ASIO 对象的 API 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59202474/