简体   繁体   中英

[boost.asio]closing tcp::socket or tcp::acceptor in different thread from the I/O thread

Could I close tcp::socket in different thread from the sync-reading thread? It looks like:

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

thread1:

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;
  }
}

thread2:

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

I saw the document of tcp::socket. They say the object is thread-unsafty.But the demo code seems working well. So Is it safe? What about tcp::acceptor? Could I invoke close and accept in multithreading on same tcp::acceptor?

The documentation states that tcp::socket is not thread safe for shared objects.

Don't count on it seemingly working as a guarantee that it will always work.

Moreover, closing a socket from another thread, at the socket layer, is not a portable way of getting the blocking thread to unblock.

Here's what I would suggest:

  • Use the asynchronous APIs for asio.
  • Protect the socket with a mutex to prevent concurrent access or use an asio strand to serialize the access to it.

Quoting the author on a similar question:

Actually...

In practice, it will probably work on the platforms asio currently supports**. However, I have deliberately specified the interface such that it is not thread safe. This is to permit implementations to store additional state in the socket object without needing explicit synchronisation.

If you want to run multiple concurrent operations on the same socket, the safe, portable way is to use the asynchronous operations.

**Unless you make the socket non-blocking.

Cheers, Chris

It is safe, as long as you can guarantee that no other thread is using the tcp_socket after closing. For your example, if thread1 was still in the read-loop while thread2 was attempting to close the thread, you will have a race-condition.

You can use thread-shared variables to signal thread1 to quit the loop and use a barrier to ensure the socket is only closed after thread1 is in a safe state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM