C++11 Когда использовать ограждение памяти?

Я пишу некоторый многопоточный код 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(), которая выполняется в другом потоке. Достаточно ли того, что оно написано в конструкторе, а затем поток создается в отдельной функции? Или мне нужно ограничение памяти, и как сделать ограничение памяти, чтобы убедиться, что все 3 аргумента записаны основным потоком, а затем прочитаны рабочим потоком?

Спасибо за любую помощь!

1 ответ

Решение

Стандартный раздел 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: синхронизация встроена в мьютексы / атомики, и они обрабатывают любые необходимые для вас ограничения. (Предостережение: вы сами по себе, если используете расслабленную атомистику.)

Другие вопросы по тегам