对共享变量执行多个原子操作

时间:2013-02-27 18:40:50

标签: c++ visual-c++ boost concurrency boost-thread

我想对共享变量进行两次操作。我需要保证它可以原子方式完成。有人可以帮我澄清以下方法是否正确:

#include <atomic>
std::atomic<int> index;

void function()
{
     // I need the variable index to be incremented but bound in the 
     // range of [0,9].
     int loc_indx = index.load(std::memory_order_acquire);
     index.store( (loc_indx+1)%10  , std::memory_order_release);
}

根据我的理解,索引存储操作和索引加载操作必须一起发生。这里的一些专家能否澄清上述代码是否等同于以下伪代码:

ATOMIC
{
   index = (index+1)%10;
}

我一直在使用Visual Studio 2012的c ++部分中的原子包或/和1.53的boost :: atomic部分。

1 个答案:

答案 0 :(得分:4)

与锁相比,原子的整个目的是提高性能。

您的代码中没有锁。 memory_order枚举只是为了确保编译器不对代码重新排序(也不让CPU重新排序)。这意味着某些其他线程很可能会修改loadstore之间的值。如果存储的值必须取决于先前的值,那么在两者之间完成的计算将被浪费,需要重做。这样做可以比锁更有效,因为并发修改实际发生的可能性很低,而且计算既便宜又简单。

知道之前的值时存储,否则重新计算并重试。类似的东西:

 int loc_index = index.load(std::memory_order_acquire);
 int desired = (loc_index+1)%10;

 while ( !index.compare_exchange_strong( loc_index, desired ) )
 {
     desired = (loc_index+1)%10;
 }

compare_exchange_strong是原子操作,用于将index中存储的值与loc_index进行比较;如果它们相等,则将desired存储到index;如果它们不相等,则会将index的值复制到loc_index。这有助于您确保下一步 存储在index中的值是正确的。