Первый вопрос: почему в аргументах операции atomic_compare_exchange_weak не применяется оценка postfix (++)? Значение a равно до и после операции. Однако при использовании в printf(), как и ожидалось, значение увеличивается.
Код:
int main(){
atomic<int> s(0);
int a = 0;
atomic_compare_exchange_weak(&s,&a,a++);
printf("%d %d\n",s.load(),a++);
printf("%d\n",a);
}
имеет следующий выход:
0 0
1
когда я ожидал этого выхода:
0 1
2
Во-вторых, я бы хотел использовать постфиксную оценку для проверки порядка атомных операций в многопоточной ситуации, мой подход здесь испорчен каким-то трагическим способом? Например, даже если оператор приращения действительно работал, может ли произойти другая операция CAS между первым CAS и оценкой приращения?
Если вы передадите a++ в качестве третьего аргумента, к моменту начала вызова функции a будет удерживать добавочное значение (см. Порядок оценки). Поскольку это значение больше не равно значению атома, CAS C++ считывает из атома и записывает во второй аргумент, что заставляет его выглядеть так, как будто приращение "не произошло".
Проверьте значение, возвращаемое CAS.
atomic_compare_exchange_weak(&s, &a, a + 1); a++;
должен работать правильно?