1

I'm writing some threaded C++11 code, and I'm not totally sure on when I need to use a memory fence or something. So here is basically what I'm doing:

class Worker
{
   std::string arg1;
   int arg2;
   int arg3;
   std::thread thread;

public:
   Worker( std::string arg1, int arg2, int arg3 )
   {
      this->arg1 = arg1;
      this->arg2 = arg2;
      this->arg3 = arg3;
   }

   void DoWork()
   {
      this->thread = std::thread( &Worker::Work, this );
   }

private:
   Work()
   {
      // Do stuff with args
   }
}

int main()
{
   Worker worker( "some data", 1, 2 );
   worker.DoWork();

   // Wait for it to finish
   return 0;
}

I was wondering, what steps do I need to take to make sure that the args are safe to access in the Work() function which runs on another thread. Is it enough that it's written in the constructor, and then the thread is created in a separate function? Or do I need a memory fence, and how do I make a memory fence to make sure all 3 args are written by the main thread, and then read by the Worker thread?

Thanks for any help!

Joe
  • 726
  • 1
  • 8
  • 18
  • Will you have only multiple threads *reading* the variables, or will there one or more *writing* to the variables? Or will you have one object instance per thread? – Some programmer dude Jun 19 '13 at 13:52
  • In this case, one thread will write the variables, and the other will read them. Also there will indeed be one object instance per thread. I'd be interested to learn what I'd need to do were that not the case though (if you have the time). Thanks =) – Joe Jun 19 '13 at 14:07

1 Answers1

6

The C++11 standard section 30.3.1.2 thread constructors [thread.thread.constr] p5 describes the constructor template <class F, class... Args> explicit thread(F&& f, Args&&... args):

Synchronization: the completion of the invocation of the constructor synchronizes with the beginning of the invocation of the copy of f.

So everything in the current thread happens before the thread function is called. You don't need to do anything special to ensure that the assignments to the Worker members are complete and will be visible to the new thread.

In general, you should never have to use a memory fence when writing multithreaded C++11: synchronization is built into mutexes/atomics and they handle any necessary fences for you. (Caveat: you are on your own if you use relaxed atomics.)

Casey
  • 41,449
  • 7
  • 95
  • 125