Код: Выделить всё
#include
#include
#include
int main() {
std::atomic strong = {3};
std::atomic weak = {1};
auto t1 = std::thread([&]() {
int expected = 1;
if (weak.compare_exchange_strong(expected, 255,
std::memory_order::acquire,
std::memory_order::relaxed) == true) {
bool unique = strong.load(std::memory_order::acquire) == 1; // #0
weak.store(1, std::memory_order::relaxed); // #1
assert(unique == false);
}
});
auto t2 = std::thread([&]() {
auto val = weak.load(std::memory_order::relaxed);
while (true) {
if (val == 255) {
std::this_thread::yield();
val = weak.load(std::memory_order::relaxed);
continue;
}
if (weak.compare_exchange_strong(
val, val + 1, std::memory_order::acquire,
std::memory_order::relaxed) == true) {
break;
}
}
strong.fetch_sub(1, std::memory_order::release); // #2
});
auto t3 = std::thread([&]() {
auto val = weak.load(std::memory_order::relaxed);
while (true) {
if (val == 255) {
std::this_thread::yield();
val = weak.load(std::memory_order::relaxed);
continue;
}
if (weak.compare_exchange_strong(
val, val + 1, std::memory_order::acquire,
std::memory_order::relaxed) == true) {
break;
}
}
strong.fetch_sub(1, std::memory_order::release); // #3
});
t1.join();
t2.join();
t3.join();
}
Если вычисление значения A атомарного объекта M происходит до операции B, которая изменяет M, то A берет свое значение из побочного эффекта X на M, где X предшествует B в порядке модификации M.
Код: Выделить всё
#1Значение атомарного объекта M, определенное оценкой B, представляет собой значение, сохраненное некоторым неуказанным побочным эффектом A, который изменяет M, где B не происходит до A.
В более общем смысле, любой поток, утверждающий, что его операция RMW на Strong будет прочитана #0 невозможно, поскольку его операция CAS на слабом не ожидает 255, а #1 не виден для части загрузки, поэтому его цикл не может выйти. И никакая другая операция RMW над слабым, увеличивающая счетчик, не может предшествовать ей; в противном случае порядок модификации слабых недействителен
Код: Выделить всё
1 < 255 < weak_store_1 < RMW_weak_a < ... < RMW_weak_current < ... < weak_store_1
Подробнее здесь: https://stackoverflow.com/questions/798 ... ther-threa
Мобильная версия