Код: Выделить всё
#include
#include
#include
std::atomic canceller = {0};
int main() {
auto t1 = std::thread([]() {
auto v = canceller.fetch_add(1, std::memory_order::relaxed); // #0
std::thread([v]() {
int current = v + 1;
if (canceller.compare_exchange_strong(
current, current, std::memory_order::relaxed,
std::memory_order::relaxed)) { // #1
// post_data_to_network(current);
}
}).join();
});
auto t2 = std::thread([]() {
canceller.fetch_add(1, std::memory_order::relaxed); // #2
});
t1.join();
t2.join();
}
Приведенный выше код моделирует такие два события. В этом случае #1 должен завершиться неудачей (обнаружить изменение) и отменить задачу, если #2 читает #0 и записывает 2. Однако, если изменить #1 на чистую загрузку, следующим образом:
Код: Выделить всё
if(canceller.load(memory_order::relaxed)==current){
// post_data_to_network(v);
}
Если побочный эффект X на атомарный объект M происходит до вычисления значения B для M, то оценка B берет свое значение из X или из побочного эффекта Y, который следует за X в порядке модификации M.
[atomics.order] p12
Реализация должна сделать атомарные хранилища видимыми для атомарных загрузок, а атомные загрузки должны наблюдать за атомарными хранилищами в течение разумного периода времени.
Теоретически, чистая загрузка в A может продолжать читать 1 в течение ограниченного времени, что не может обнаружить изменение #0 в B, даже если #2 изменил значение.
/>При той же модификации подпоследовательности в порядке модификации отмены:
Код: Выделить всё
0 < #0 < #2 < ...
Итак, мне интересно, имеет ли CAS, записывающий одно и то же значение, более высокую вероятность обнаружения изменения, чем чистая загрузка? Если нет, то как доказать, что их показатели успеха равны?
Подробнее здесь: https://stackoverflow.com/questions/798 ... -higher-pr
Мобильная версия