该网站解释了C++11原子学,并给出了默认std::atomic<T>
类型未提供的原子fetch_mult
操作的示例实现:
#include <atomic>
#include <iostream>
template <typename T>
T fetch_mult(std::atomic<T>& shared, T mult){
T oldValue= shared.load();
// 1
while (!shared.compare_exchange_strong(oldValue, oldValue * mult));
return oldValue;
}
int main(){
std::atomic<int> myInt{5};
std::cout << myInt << std::endl;
fetch_mult(myInt,5);
std::cout << myInt << std::endl;
}
我无法理解此功能。如果fetch_mult
在第// 1
点被另一个也调用fetch_mult
的线程中断,那么其中一个线程死锁,因为compare_exchange_strong
永远不会返回true
,除非mult==1
或其他线程将值设置回oldValue
?
例如(T1 和 T2 是各自的线程(:
- T1:
oldValue = 5;
- T2:
oldValue = 5;
- T2:
compare_exchange_strong
成功将值设置为25
- T1:
compare_exchange_strong
永远不会成功完成,因为它的oldValue
仍然5
,除非其他人再次将值设置为5
我的理解正确吗?如果是这样,这会是fetch_mult
的正确实现吗?
template <typename T>
T fetch_mult(std::atomic<T>& shared, T mult){
while (true) {
T oldValue = shared.load();
if (shared.compare_exchange_strong(oldValue, oldValue * mult))
return oldValue;
}
}
如果比较失败,atomic::compare_exchange_*
将当前值加载到"预期"参数中。在您的示例中,在步骤 4 中,T1 将失败比较交换并将 25 加载到oldValue
中,然后在下一次迭代中成功。