title: write to boost::asio socket from different threads
body: <p>In our application we use Boost libraries (and ASIO for network communications). </p>
  
  <p>Recently, we discovered that if we're sending our data from different threads via same socket, our client application is receiving garbaged data.</p>
  
  <p>Small test to highlight the issue:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;boost/thread.hpp&gt;
  #include &lt;boost/asio.hpp&gt;
  
  void send_routine(boost::shared_ptr&lt;boost::asio::ip::tcp::socket&gt; s, char c)
  {
    std::vector&lt;char&gt; data(15000, c);
    data.push_back('\n');
  
    for (int i=0; i&lt;1000; i++)
      boost::asio::write(*s, boost::asio::buffer(&amp;data[0], data.size()));
  }
  
  
  int main()
  {
    using namespace boost::asio;
    using namespace boost::asio::ip;
  
    try {
      io_service io_service;
      io_service::work work(io_service);
  
      const char* host = "localhost";
      const char* service_name = "18000";
  
      tcp::resolver resolver(io_service);
      tcp::resolver::query query(tcp::v4(), host, service_name);
      tcp::resolver::iterator iterator = resolver.resolve(query);
  
      auto socket = boost::shared_ptr&lt;tcp::socket&gt;(new tcp::socket(io_service));
      socket-&gt;connect(*iterator);
  
      boost::thread t1(send_routine, socket, 'A');
      boost::thread t2(send_routine, socket, 'B');
      boost::thread t3(send_routine, socket, 'C');
  
      t1.join();
      t2.join();
      t3.join();
    }
    catch (std::exception&amp; e) {
      printf("FAIL: %s\n", e.what());
    }
      return 0;
  }
  </code></pre>
  
  <p>So, we create socket here, connect to <code>localhost:18000</code> and start 3 threads which will write to the socket.</p>
  
  <p>In different terminal window, I run <code>nc -l -p 18000 | tee out.txt | sort | uniq | wc -l</code>. I expect <code>3</code> as output, but it returns more then 100 "different strings" in the network stream (so, data is corrupted). But it works with small buffer sizes (if we'll change <code>15000</code> to <code>80</code>, for example).</p>
  
  <p>So, the question is: is it a correct behavior of ASIO library? And another: how to fix it? Should I use <code>mutex</code> inside my <code>send_routine</code> function (or there is another solution)?</p>