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