1

我正在编写一些线程化的 C++11 代码,但我不确定何时需要使用内存围栏或其他东西。所以这基本上就是我正在做的事情:

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

我想知道,我需要采取哪些步骤来确保在另一个线程上运行的 Work() 函数中可以安全地访问 args。写在构造函数中,然后在单独的函数中创建线程就够了吗?或者我是否需要一个内存栅栏,我如何制作一个内存栅栏以确保所有 3 个 args 都由主线程写入,然后由 Worker 线程读取?

谢谢你的帮助!

4

1 回答 1

6

C++11 标准第 30.3.1.2 节线程构造函数 [thread.thread.constr] p5 描述了构造函数template <class F, class... Args> explicit thread(F&& f, Args&&... args)

同步:构造函数调用的完成与副本的调用开始同步f

所以当前线程中的一切都发生在线程函数被调用之前。您不需要做任何特别的事情来确保对Worker成员的分配是完整的并且将对新线程可见。

一般来说,在编写多线程 C++11 时,您永远不必使用内存栅栏:同步内置于互斥锁/原子中,它们会为您处理任何必要的栅栏。(警告:如果你使用宽松的原子,你就靠自己了。)

于 2013-06-19T14:24:45.967 回答