前提:回忆使用 互斥量加锁 完成共享数据的访问。
mutex mymutex; //锁子
mymutex.lock();
// 锁住完成的代码
mymutex.unlock();
一 互斥量好是好,但是在这种case下,效率并不高,因此C++给我们提供了原子操作的概念,并给我们了automic关键字来实现这个
case 是,只是对某一个变量进行++,--等操作。
i++;
像这样的++操作,在观察汇编代码的时候会发现,会变成3步完成,因此可能会有共享数据的问题,也就是说,按照我们之前的学习,也要用 mymutex.lock()和 mymutex.unlock();
二 原子操作概念:
换成汇编的操作,不管几步,要不一起执行,要不都不执行。
三 atomic 关键字,对于++,--,+=,-=,&=,|= ,^= 都是支持的。
class Teacher182 {
public:
mutex mymutex;
list<int> mylist;
int num = 0;
atomic<int> numau = 0;
public:
int readfunc(string &tempstr) {
for (size_t i = 0; i < 10000; i++)
{
//mymutex.lock();
//cout << "read func tempstr = " << tempstr << " i = " << i << " threadid = " << this_thread::get_id() << " &tempstr = " << &tempstr << " tempstr = " << tempstr << " num = " << num << endl;
//mymutex.unlock();
numau;
}
return 10;
}
int writefunc(const int &tempdouble) {
for (size_t i = 0; i < 10000; i++)
{
//mymutex.lock();
//num++;
//cout << "write func tempdouble = " << tempdouble << " i = " << i << " threadid = " << this_thread::get_id() << " &tempdouble = " << &tempdouble << " tempdouble = " << tempdouble << "num = " << num << endl;
//mymutex.unlock();
numau++;
}
return (int)tempdouble;
}
};
//aotomic
void main() {
Teacher182 tea;
string sourcestr = "nihao";
double dou = 20.8;
thread myreadthread(&Teacher182::readfunc,&tea,ref(sourcestr));
thread mywritethread(&Teacher182::writefunc,&tea,ref(dou));
myreadthread.join();
mywritethread.join();
}
四 坑点
atomic<int> numau = 0;
在线程中,numau++ 是原子操作的,但是cout<<是没有原子操作的
cout<< numau++ <<endl;
五 load() 函数
读取包含的值,返回包含的值。该操作是原子操作。
atomic<int> num = 10;
num.load();
六 store() 函数
修改包含的值。将包含的值替换为val。该操作是原子操作。
atomic<int> num = 10;
int value = num.load();//从 num 读取值
cout << "value = " << value << endl;
atomic<int> num2 = value; //将值直接赋值给 atomic
cout << "num2 = " << num2 << endl;
//atomic<int> num3(num2);//atomic无法直接赋值给atomic,build error
//atomic<int> num3 = num2;//atomic无法直接赋值给atomic,build error
atomic<int> num3(num2.load());
cout << "num3 = " << num3 << endl;
num3 = 999; //给 atomic 直接 赋值
cout << "num3 = " << num3 << endl;
num3.store(888999); //给 atomic 通过store赋值
cout << "num3 = " << num3 << endl;