title: Thread safety and std::move
body: <p><hr/>
  <strong>Preface:</strong>
  When I'm typing out new code, I declare my functions as <em>pass-by-reference-to-const</em> without thinking (out of habit), and sometimes have to go back and change it when I realize it's not what I meant to do. </p>
  
  <p>I'm writing a worker-thread class that runs indefinitely, and is fed strings (from another thread) for processing. When I realized that I had declared the function as <em>pass-by-ref</em>, I went back to change it to <em>pass-by-value</em>, for thread-safety.</p>
  
  <p>But, since I would like to squeeze out as much speed and efficiency as possible, I stopped myself to first explore the options. I wrote a little test routine - and discovered that I'm fuzzy on some key concepts.
  <hr/>
  <strong>To the point:</strong> I first wrote the test code below without the commented line:</p>
  
  <pre><code>// std::thread _thread(workthread, move(str)); // Thread safe (contents are moved)
  </code></pre>
  
  <p>So, ignore that line for now.</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;string&gt;
  #include &lt;thread&gt;
  #include &lt;chrono&gt;
  #include &lt;atomic&gt;
  
  std::atomic&lt;bool&gt; done = false;
  
  void workthread(const std::string &amp;str)
  {
      std::string &amp;s = const_cast&lt;std::string &amp;&gt;(str);
      s = "Work Thread"; // test to see if this changes the main thread's string
  }
  
  // This just watches for &lt;enter&gt; on the keyboard in order to quit the program.
  void quitmonitor()
  {
      std::getchar();
      done = true;
  }
  
  int main(int argc, char **argv)
  {
      std::thread _monitor(quitmonitor);
      std::string str("Main Thread");
  
      std::thread _thread([&amp;]{workthread(std::move(str));}); // Not thread safe (address is copied)
  //  std::thread _thread(workthread, move(str));            // Thread safe (contents are moved)
  
      const auto minlen(str.length());
      const auto maxlen(minlen ? minlen*2 : 15);
      bool going_up = true;
  
      while (!done) {
  
          if (going_up)
              str.push_back('+');
          else
              str.pop_back();
  
          if (str.length() == minlen)
              going_up = true;
          if (str.length() == maxlen)
              going_up = false;
  
          std::cout &lt;&lt; str &lt;&lt; "\n";
          std::this_thread::sleep_for(std::chrono::milliseconds(100));
      }
  
      _thread.join();
      _monitor.join();
  }
  </code></pre>
  
  <p>All <code>main()</code> does is create a string <em>"Main Thread"</em>, and moves it to the thread function <code>void workthread(const std::string &amp;)</code>. The thread function then changes the lvalue's data and returns. The main continues on to a loop which just prints its local string to console (with some additional eye-candy to make it easy to see things happening on the screen). Here's the output:</p>
  
  <p><a href="https://i.stack.imgur.com/j6t9V.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/j6t9V.png" alt="function called with lambda"></a></p>
  
  <p>So, it didn't work as I had expected. I had thought that the thread instantiation would "move" <code>str</code> to the thread function (emptying its data in the process), and the thread's assignment to the function's string argument would have no affect. But clearly it did, as demonstrated by the output.</p>
  
  <p>This must have something to do with the fact that I constructed <code>_thread</code> with a lambda:
  <code>std::thread _thread([&amp;]{workthread(std::move(str));}); // Not thread safe (address is copied)</code></p>
  
  <p>So then I changed the instantiation to:
  <code>std::thread _thread(workthread, move(str));  // Thread safe (contents are moved)</code>
  and it worked as expected:
  <a href="https://i.stack.imgur.com/EjC2w.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/EjC2w.png" alt="function called as bind"></a></p>
  
  <p><strong>Q1:</strong> Why do the two instances, lambda vs bind<sub>(I guess?)</sub>, yield different results?</p>
  
  <p><strong>Q2:</strong> Am I actually buying myself anything by declaring this as <em>pass-by-reference</em>?</p>
  
  <p><em>I should note that the actual program is quite time critical, and is intended to run uninterrupted for years on a dedicated server. I'm trying to make the software as low-overhead as possible, to ensure that it can stay in sync (with an external clock), and not accumulate time errors.</em></p>