c++ - 同时调用 ASIO 对象的 API 是否安全?

标签 c++ boost-asio

我是 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/

相关文章:

c++ - 在类定义中使用 'this'

c++ - 包含基元和对象的成员 union 如何在 C++ 中初始化?

c++ - "expected type-specifier"尝试从模板类创建 .o

c++ - 将回调从 C++ 转发到 ObjC

c++ - Unique_ptr 将所有权移动到包含对象的方法

c++ - Boost::bind 一个带有 boost::function 参数的方法

c++ - 使用 libcurl 和 Fiddler 拦截 HTTPS 流量

c++ - Thrift 在 SSL_accept 上随机崩溃

内存碎片@ boost::asio?

C++ 升压 ASIO : how to read/write with a timeout?