【2】原子操作比互斥量在效率上更高;
【3】互斥量的加锁一般是针对一个代码段(几行代码), 原子操作针对的都是一个变量,而不是针对一个代码段; 【4】原子操作:该变量要么完成,要么没完成,不存在中间状态
std::atomic代表原子操作。std::atomic是一个类模板,用于封装某个类型的值; 2.原子操作步骤(分三步:Read ---> Modified ----> Write) atomic是原子的意思,意味"不可分割"的整体。在Linux kernel中有一类atomic操作API。这些操作对用户而言是原子执行的,在一个CPU上执行过程中,不会被其他CPU打断。最常见的操作是原子读改写,简称RMW。
【1】单个CPU的情况
一个变量自增操作,CPU微观指令级别分成3步操作。 1) 先read变量的值到CPU内存寄存器; //读:Read 2) 对寄存器的值递增;//改:Modified 3) 将寄存器的值写回变量。//写: Write3.多线程访问一个变量例子
【1】有两个线程,线程thread1对变量aa读操作,线程thread2对变量中写值。
int aa = 5;
【2】在线程thread1里,对aa读操作,放入tmp变量中,以后使用
int tmp = aa ;//aa代表的是多个线程之间要共享的变量
【3】在线程thread2里,对aa写操作
aa = 100;
结果:原本是想读出来aa = 5的值,结果可能读出来是已经修改的值100,不是自己想要的脏数据,所以对变量读写要保持其原子性----->即:执行中不可被打断。
原子操作:
可以把原子操作理解为:不需要用到互斥量加锁(无锁)技术的多线程编程方式,多线程中不会被打断的程序执行片段。
#include#include #include using namespace std; //1.have atomic //atomic g_count; //2.no atomic int g_count = 0; void work(){ for (int i = 0;i < 100000;i++){ g_count++; } return; } int main(){ std::thread t1(work); std::thread t2(work); t1.join(); t2.join(); //如果没有使用atomic原子定义,打印的值是随机,是乱的 cout << "g_count = " << g_count << endl; }
总结:
1.先理解下CPU和内存连接方式
在SMP系统中,多个CPU通过共享的总线和内存相连接,如果它们同时申请访问内存,那么总线就会从硬件上进行仲裁,以确定接下来哪一个CPU可以使用总线,然后将总线授权给它,并且允许该CPU完成一次原子的load操作或者store操作。在完成每一次操作之后,就会重复这个周期:对总线进行仲裁,并授权给另一个CPU。每次只能有一个CPU使用总线。
2.理解原子操作
原子操作常用的做法是给总线上锁(bus lock),以获得在一定的时间窗口内对总线独占的授权,就好像是一个CPU在告诉总线说“在我完成之前,别让其他CPU来读写内存的数据”。



