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

Is it safe to call APIs of ASIO objects concurrently?

本文关键字:API 是否 安全 对象 调用 ASIO      更新时间:2023-10-16

我是ASIO的新手,喜欢了解线程安全的工作原理,以便我可以弄清楚在使用ASIO API时可以做出哪些假设。

到目前为止,我发现了什么:

多个线程可以运行io_service.run()

因此,可能会调用类(如socket(中的处理程序 来自不同的线程,但仅来自执行io_service.run()的线程。

假设socket具有必须保护的内部状态 从并发访问。

socket会用一个strand来包装它的处理程序,这序列化了执行 的处理程序。它与在每个中获取互斥锁具有基本相同的效果 处理程序,但性能更好。

socket也有公共方法,比如socket.async_write_some()。它 也可以从不同的线程调用。

假设socket.async_write_some()访问相同的内部状态, 所以需要一些保护机制。

公共方法如何以安全的方式访问内部状态?

  • strand可用于序列化公共方法的调用吗?

  • 在公共方法中调用post([]{ /* actual implementation of the method goes here */})

  • 除了链之外,还使用互斥锁?

调用公共 API 时可以做出哪些假设?

我是否可以假设socket保护其内部状态,即使我从未调用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(隐式或显式(来确保这一点。