Если у меня есть один поток, «основной» поток, инициализирующий глобальную переменную, и этот поток позже порождает некоторые потоки, которые обращаются к этой переменной, мне нужно выполнять какую-либо работу, например, вызов std :: atomic_thread_fence (memory_order_seq_cst), чтобы гарантировать, что переменная будет инициализирована для новых потоков? Я подозреваю, что тот факт, что основной поток создает новые потоки, устанавливает отношение «синхронизировано с», достаточное для предотвращения любых гонок, но я не уверен.

Вот псевдокод того, что я описываю:

class MyApi {
public:
    static void init(Foo *foo) {
        MyApi::foo = foo;
    }

    static Foo* getSharedFoo() {
        return foo;
    }

private:
    static Foo* foo;
};

void main() {
    Foo* foo = new Foo();
    MyApi::init(foo);
    // Spawn threads that will call MyApi::getSharedFoo() and expect
    // to receive the same foo that is created above.
}
3
Christopher Simmons 25 Ноя 2016 в 22:36

2 ответа

Лучший ответ

Нет, ничего особенного делать не надо. Новые потоки видят все изменения памяти до того момента, когда они были созданы.

2
Pete Becker 25 Ноя 2016 в 19:44

30.3.1.2 конструкторы потоков

[...] шаблон явного потока (F && f, Args && ... args);

[...]

Синхронизация: завершение вызова конструктора синхронизируется с началом вызова копии f.

Это указывает, что f видит все, что произошло до создания объекта std::thread, породившего поток.

0
Sam Varshavchik 25 Ноя 2016 в 20:09