C++中有atomic类和atomic_flag两个类,其中atomic类用于定义一个原子操作,atomic_flag定义一些与原子操作相关的函数
如下操作:
// atomic原子操作.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <atomic>
#include <iostream>
#include <thread>
using namespace std;
//atomic<int> N = 0;
int N = 0;
void threadFun()
{
for (int i = 0; i < 1000000; ++i)
++N;
}
int main()
{
thread t1(threadFun);
thread t2(threadFun);
t1.join();
t2.join();
cout << N << endl;
return 0;
}
一般的操作如上,我们开启两个线程,定义一个全局变量N,定义一个线程函数,想要执行的功能是没执行一次函数就让全局变量N加1,每个线程单独加1000000次,两个线程,我们期望的结果是2000000,但是结果如上图所示,多次实验结果不一样,但是总不会(概率很小)出现我们期望的结果,这是因为,我们对变量N的操作是非原子性的,线程A执行++的时候,线程B也在执行++,有可能两个线程是对同一个值进行相同的++操作,这样最后得出的结果就是执行了一次++操作,所以最后结果会小于200000,。
我们把N定义成一个原子变量,即在N上的操作是具有原子性的,每个线程在执行++操作是不会被另一个线程打断,只有++执行完毕另一个线程才会执行自己的++动作
// atomic原子操作.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <atomic>
#include <iostream>
#include <thread>
using namespace std;
atomic<int> N = 0;//定义N为原子变量
//int N = 0;
void threadFun()
{
for (int i = 0; i < 1000000; ++i)
++N;
}
int main()
{
thread t1(threadFun);
thread t2(threadFun);
t1.join();
t2.join();
cout << N << endl;
return 0;
}
我们把N定义为atomic<int> 类的一个对象,使得在N上的操作具有原子性,如此我们得到的结果就是所期望的值