This site解释了C++ 11原子,并给出了默认fetch_mult
类型未提供的原子std::atomic<T>
操作的示例实现:
#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是各自的线程):
oldValue = 5;
oldValue = 5;
compare_exchange_strong
成功将值设置为25
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_*
将当前值加载到“expected”参数中。在您的示例中,在步骤4中,T1将使compare-exchange失败,并将25加载到oldValue
中,然后在下一次迭代中成功。