[boost.asio]在I / O线程的不同线程中关闭tc​​p :: socket或tcp :: acceptor

时间:2012-03-05 07:31:53

标签: c++ boost boost-asio

我可以在同步读取线程的不同线程中关闭tc​​p :: socket吗? 它看起来像:

boost::asio::ip::tcp::socket* tcp_socket;  //blocking mode

线程1:

while(true){
   try{
       std::vector<char> read_buffer(10);
       tcp_socket->read_some( boost::asio::buffer( read_buffer ) );
  }
  catch(boost::system::system_error& e){
  //TODO
  break;
  }
}

线程2:

tcp_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
tcp_socket->close();

我看到了tcp :: socket的document。他们说这个对象是线程不健全的。但是演示代码似乎运行良好。 那么安全吗?那么tcp :: acceptor呢?我可以在多线程中调用close和accept 在同一个tcp :: acceptor?

2 个答案:

答案 0 :(得分:5)

文档指出tcp::socket对共享对象不是线程安全的。

不要指望它似乎能够保证它始终有效。

此外,在套接字层关闭来自另一个线程的套接字并不是一种让阻塞线程解除阻塞的可移植方式。

以下是我的建议:

  • 使用asio的异步API。
  • 使用互斥锁保护套接字以防止并发访问或使用asio strand序列化对它的访问。

similar问题上引用作者:

  

实际上...

     

在实践中,它可能会在asio平台上运行   支持**。但是,我故意指定了这样的接口   它线程安全。这是为了允许实现   在socket对象中存储其他状态而不需要显式   同步。

     

如果要在同一个套接字上运行多个并发操作,   安全,可移植的方式是使用异步操作。

     

**除非你使套接字无阻塞。

     

干杯,克里斯

答案 1 :(得分:2)

这是安全的,只要您可以保证在关闭后没有其他线程正在使用tcp_socket。对于您的示例,如果thread1仍在读取循环中而thread2尝试关闭该线程,则您将遇到竞争条件。

您可以使用thread-shared variables向thread1发出信号以退出循环并使用a barrier确保套接字仅在thread1处于安全状态后关闭。

相关问题