Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对共享变量执行多个原子操作_C++_Visual C++_Boost_Concurrency_Boost Thread - Fatal编程技术网

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

C++ 对共享变量执行多个原子操作,c++,visual-c++,boost,concurrency,boost-thread,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

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

#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);
}

我一直在Visual Studio 2012的C++部分中使用原子包,而/Boost::1.53的原子部分。

< P>原子的全部目的是提高与锁相比的性能。

代码中没有锁。
memory\u顺序
enum只是为了确保编译器不会对代码重新排序(也不会让CPU对代码重新排序)。这意味着其他线程修改
load
store
之间的值的可能性很小。如果存储的值必须依赖于前一个值,则在这两个值之间进行的计算将被浪费,需要重新进行。这样做比锁的效率要高得多,因为并发修改实际发生的几率很低,而且计算既便宜又简单

知道上一个值时存储,否则重新计算并重试。比如:

 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\u exchange\u strong
是一种原子操作,它将存储在
索引中的值与
loc\u索引进行比较;如果它们相等,它将
所需的
存储到
索引中
;如果它们不相等,它会将
索引的值复制到
locu index
中。这有助于您确保下一个
存储在
index
中的值是正确的。

是否所有线程都通过调用
function()
来访问
index
?或者他们可以随意访问
索引
吗?增量只能通过所有线程调用
函数()
来完成。是的,有更多线程同时访问
函数()
。您缺少
在第4行(从1:-)开始)。如果您可以添加一些解释,那将非常有用。@goutham-调用
比较交换(strong
索引
中存储的值与
定位索引
进行比较;如果它们相等,它将
所需的
存储到
索引中
;如果它们不相等,它会将
索引的值复制到
locu index
中。所有这些都是原子化的。在第一种情况下返回true,在第二种情况下返回false。相当密集,不是吗<代码>
。(空间不足;请参见下一条评论)@goutham(继续上一条评论)-本质上,它不断从
索引中加载新值,增加其值,并将结果存储到
所需的
。然后检查
索引中的值自上次加载以来是否发生了更改;如果没有,它将
所需的
存储到
索引中
并退出循环。另一方面,如果这个值改变了,那么其他线程在这个线程的工作中间做了更新,所以它必须再次尝试,使用新的值<代码>索引< /代码>。我添加了一些文字来讨论背景。希望它能解释为什么操作代码太幼稚。
 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;
 }