C++中的原子操作

一、概述

C++11提供了一个原子类型 std::atomic<T>, 通过这个原子类型管理的内部变量就可以称之为原子变量,我们可以给原子类型指定 bool、char、int、long、指针 等类型作为模板参数(不支持浮点类型和复合类型)。

原子指的是一系列不可被CPU上下文交换的机器指令,这些指令组合在一起就形成了原子操作。在多核CPU下,当某个CPU核心开始运行原子操作时,会先暂停其它CPU内核对内存的操作,以保证原子操作不会被其它CPU内核所干扰。

由于原子操作是通过指令提供的支持,因此它的性能相比锁和消息传递会好很多。相比较于锁而言,原子类型不需要开发者处理加锁和释放锁的问题,同时支持修改,读取等操作,还具备较高的并发性能,几乎所有的语言都支持原子类型。

 

二、实验

1. 原子变量计数与耗时实验

(1) counter_test.cpp

#include <thread>
#include <atomic>
#include<mutex>
#include <iostream>

using namespace std;

#define POLICY_ATOMIC //POLICY_MUTEX POLICY_ATOMIC POLICY_NO

const int maxCnt = 1000000;

#ifdef POLICY_NO
int gConter = 0;
void mythread()
{
    for (int i = 0; i < maxCnt; i++) {
        gConter++;  //线程同时操作变量
    }
}
#endif

#ifdef POLICY_MUTEX
int gConter = 0;
mutex mut;
void mythread()
{
    for (int i = 0; i < maxCnt; i++) {
        mut.lock();    //加锁操作
        gConter++;
        mut.unlock();
    }
}
#endif

#ifdef POLICY_ATOMIC
atomic<int> gConter;
void mythread()
{
    for (int j = 0; j < maxCnt; j++) {
        gConter++;
    }
}
#endif

int main()
{
    auto begin = chrono::high_resolution_clock::now();
    thread t1(mythread);
    thread t2(mythread);
    t1.join();
    t2.join();
    auto end = chrono::high_resolution_clock::now();
    cout << "gConter=" << gConter << endl;
    cout << "time: " << chrono::duration_cast<chrono::microseconds>(end - begin).count() * 1e-6 << "s" << endl; //秒计时
}

 

(2) 结果

~/tmp/3.cpp_test/2.atomic$ g++ -std=c++11 counter_test.cpp -lpthread -o pp

~/tmp/3.cpp_test/2.atomic$ ./pp
gConter=1487831
time: 0.0155s

~/tmp/3.cpp_test/2.atomic$ ./pp 使用muetx
gConter=2000000
time: 0.192604s

~/tmp/3.cpp_test/2.atomic$ ./pp 原子操作的
gConter=2000000
time: 0.052044s

 

posted on 2024-04-23 16:36  Hello-World3  阅读(463)  评论(0编辑  收藏  举报

导航