Alex Rivera | Logout

boost::asio::socket thread safety

Asked 2011-09-09T14:06:20.877
25

( This is a simplified version of my original question )

I have several threads that write to a boost asio socket. This seems to work very well, with no problems.

The documentation says a shared socket is not thread safe( here, way down at the bottom ) so I am wondering if I should protect the socket with mutex, or something.

This question insists that protection is necessary, but gives no advice on how to do so.

All the answers to my original question also insisted that what I was doing dangerous, and most urged me to replace my writes with async_writes or even more complicated things. However, I am reluctant to do this, since it would complicate code that is already working and none of the answerers convinced me they knew what they ware talking about - they seemed to have read the same documentation as I and were guessing, just as I was.

So, I wrote a simple program to stress test writing to a shared socket from two threads.

Here is the server, which simply writes out whatever it receives from the client

int main()
{
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3001));

    tcp::socket socket(io_service);
    acceptor.accept(socket);

    for (;;)
    {
        char mybuffer[1256];
        int len = socket.read_some(boost::asio::buffer(mybuffer,1256));
        mybuffer[len] = '\0';
        std::cout << mybuffer;
        std::cout.flush();

    }

  return 0;
}

Here is the client, which creates two threads that write to a shared socket as fast as they can

boost::asio::ip::tcp::socket * psocket;

void speaker1()
{
    string msg("speaker1: hello, ser
Edit
Report

1 Answer

0

It depends if you access same socket object from several threads. Let's say you have two threads running same io_service::run() function.

If for example you do reading and writing simultaneously or may be perform cancel operation from other thread. Then it is not safe.

However if your protocol does only one operation in a time.

  1. If only one thread runs the io_service run then there is no problem. If you want to execute something on the socket from other thread you may call io_service::post() with handler that does this operation on socket so it would be executed in the same thread.
  2. If you have several threads executing io_service::run and you try to do operations simultaneously - let's say cancel and read operation then you should use strands. There is a tutorial for this in Boost.Asio documentation.
answered 2011-09-09T15:39:54.060

Your Answer