为什么 Boost ip::udp::socket 不是线程安全的?

问题描述

根据 boost 文档 - https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/reference/ip__udp/socket.html,ip::udp::socket 对于共享对象不是线程安全的。

但是,如果我们查看用于套接字编程的底层 UNIX API,则 SOCK_DGRAM 套接字上的 recv() 是线程安全的。我们知道这一点是因为此处记录了不安全操作的列表 - https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 和 recv() 不存在。

解决方法

这是因为从不同线程访问对象会构成数据竞争。

posix API 中的文件描述符也是如此。这是可笑错误的常见来源,例如关闭/重用文件描述符上的 ABA 问题。

最后注意,如果类

  • 实际上不存储除文件描述符之外的任何其他状态
  • 您只使用安全的底层系统调用,
  • 你使用的所有成员在逻辑上都是常量(不改变任何东西)

可能在没有同步的情况下使用这些 IO 对象实际上是安全的。只是文档不能保证

这是一个很好的实践/好的库设计:你有一个接口合同,其中记录了保证。其余的是实现细节。实施细节可能会随着时间的推移而发生变化,您无法重新检查每次更新时额外的“假定保证”是否仍然有效。