如何在C ++中为共享计数器

时间:2018-02-15 07:46:57

标签: c++ multithreading concurrency

我试图学习没有锁的并发性。因此,我试图为共享变量计数器实现简单的比较和交换(cas)。我试图创建10个线程,并希望使用CAS将每个线程的计数器值增加1。因为CAS存储旧值并与当前值进行比较,并且仅在值未更改时才更新。看[这里]我试图实施CAS,但无法做到正确。如何在c ++中实现计数器共享变量的CAS?

#include <iostream>
#include <thread>
#include <unistd.h>
#include <atomic>



std::atomic<int> count = 0;
std::mutex n_mutux;

void increase_counter(int i)
{
    int old_value = count.load() ;
    while (!count.compare_exchange_weak(old_value, old_value +1))
    {
    }



}
int main() {

    int thread_num =10;
    std::thread t[thread_num];
    for(int i=0;i<thread_num;i++)
    {
        t[i]=std::thread((increase_counter),i);
    }

    for(int i=0;i<thread_num;i++)
    {
        t[i].join();
    }
   std::cout<<count;
}

1 个答案:

答案 0 :(得分:3)

您的解决方案是正确的。

另一种方法是使用增量,请参阅std::atomic::operator++()fetch_add(1, std::memory_order_acq_rel)。这两个不需要繁忙的等待循环。

std::atomic<int> count = 0的初始化存在编译器错误。修正:

std::atomic<int> count{0};

效率稍高的CAS是:

void increase_counter(int i) {
    int old_value = count.load() ;
    while(!count.compare_exchange_weak(old_value, old_value + 1,
                                       std::memory_order_release,
                                       std::memory_order_relaxed)) 
        _mm_pause();
}

Pause Intrinsic

  

pause内在函数用于自旋等待循环,处理器实现动态执行(特别是乱序执行)。在自旋等待循环中,pause内在函数提高了代码检测到锁定释放的速度,并提供了特别显着的性能提升。

     

下一条指令的执行会延迟执行特定的时间。 pause指令不会修改体系结构状态。对于动态调度,pause指令减少了从自旋循环退出的惩罚。

有关详细信息和基准,请参阅Benefitting Power and Performance Sleep Loops