Барьеры и точки синхронизации с неатомарными переменными — гонка данных?

Рассмотрим следующую программу:

int                        i{0};
std::experimental::barrier b{2};

int main()
{
std::thread t0{[] {
b.arrive_and_wait();
std::cout << i << '\n';
}};

std::thread t1{[] {
i = 2;
b.arrive_and_wait();
}};

t0.join();
t1.join();
}

Эта программа гарантированно распечатает 2, даже если i не является атомарной переменной?

В соответствии с cppreference:

Звонки в arrive_and_wait синхронизируется с началом фазы завершения барьера. Завершение фазы завершения синхронизируется с возвратом из вызова.

Звонки в arrive_and_drop а также arrive_and_wait никогда не вводите данные о гонках с собой или друг с другом.

Это говорит о том, что есть точка синхронизации на каждом arrive_and_wait вызов. Однако я не уверен, разрешено ли компилятору переупорядочивать операции чтения / записи на i, поскольку это не атомное.

6

Решение

Из того, что я понимаю из std :: барьерная ссылка(мой акцент):

Барьер имеет фазу завершения, которая выполняется одним из участвующих потоков, как только все потоки в наборе участвующих потоков достигают точки синхронизации. Вызовы receive_and_wait и Arrive_and_drop синхронизируются с началом фазы завершения; TКонец фазы завершения синхронизируется с возвратами всех вызовов, заблокированных его завершением..

Вы можете предположить, что все изменения, сделанные до барьера в разных потоках, видны в других потоках, даже если они не являются атомарными. Как эта ссылка указывает (мой акцент):

Между потоками оценка A происходит между потоками перед оценкой B, если выполняется любое из следующих условий

1) А синхронизируется с Б

2) A упорядочен по зависимости перед B

3) А синхронизируется — с некоторой оценкой X, а X — перед B

4) A секвенируется — до некоторой оценки X, а X inter-thread происходит — до B

5) Интерпоток происходит до некоторой оценки X, а X межпоток происходит до B

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]