fetch_mult的原子实现是否正确?



该网站解释了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中,然后在下一次迭代中成功。

相关内容

  • 没有找到相关文章

最新更新