程序地带

C++11多线程的原子操作


我们知道当一个程序创建多线程运行时,多个线程之间会互相抢占。


所以即使此时运行最简单的a++;也可能会发生线程x的a++还没运行完,另一个线程y可能就抢占运行了,所以此时x线程a++就发生了错误。


下面就进行不同情况下的运行情况和时间消耗对比。


一,不加限制运行

代码:


#include<iostream>
#include<thread>
using namespace std;
const int tcount = 4;
int sum = 0;
void mythread()
{
for (int i = 0; i < 400000; i++)
{
sum++;
}
}
int main()
{
thread t[tcount];
for (int i = 0; i < tcount; i++)
{
t[i] = thread(mythread);
}
for (int i = 0; i < tcount; i++)
{
t[i].join();
}
cout<<"sum=" << sum << endl;
cout << "Hello,main thread" << endl;
system("pause");
return 0;
}

程序运行截图:



因为开了四个线程,每个线程都加了400000次,正常运行结果应该为1600000。可见这个结果是错误的,所以这种方法直接不能用。


二,将自加的过程上锁运行:mutex

不需要加太多代码:只需要加上头文件#include<mutex>


以及自加前后加锁解锁


        m.lock();         sum++;         m.unlock();


运行结果:



可见这个结果是正确的,但是试想一些加上锁的运行过程,进行了1600000次的加锁解锁的过程。对于资源的消耗很大,而且也浪费时间,所以此时就有了atomic。


三,使用原子性操作:atomic

atomic就是原子性操作,不用再加锁解锁,减少资源消耗。


修改部分:需要加上头文件<atomic>


然后把变量定义为原子的即可,下面直接自加就行;


atomic<int> sum_atomic = 0;


sum_atomic++;


运行结果:



可见这个也能运算成功,结果也是1600000。


使用时间对比两者的速率

代码:


#include<iostream>
#include<thread>
#include<mutex>
#include<chrono>
#include<atomic>
using namespace std;
using namespace std::chrono;
atomic<int> sum_atomic = 0;
mutex m;
const int tcount = 4;
int sum = 0;
void mythread()
{
for (int i = 0; i < 400000; i++)
{
//m.lock();
//sum++;
//m.unlock();
sum_atomic++;
}
}
int main()
{
thread t[tcount];
for (int i = 0; i < tcount; i++)
{
t[i] = thread(mythread);
}
time_point<high_resolution_clock> _begin=high_resolution_clock::now();;
for (int i = 0; i < tcount; i++)
{
t[i].join();
}
double now = ((long long)duration_cast<microseconds>(high_resolution_clock::now() - _begin).count())*0.001;
cout << "花费时间:" << now;
cout<<"sum_atomic=" << sum_atomic << endl;
//cout<< "sum=" << sum << endl;
cout << "Hello,main thread" << endl;
//631.275
//55.85
//9.973
system("pause");
return 0;
}

两种运行截图对比:



可见使用原子性操作的时间消耗相比于加锁解锁时间减少了500多毫秒。


因此使用原子性操作是最好的方法。


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_46423166/article/details/111246391

随机推荐

用python批量发送短信_Python批量发短信

PHP代码示例//接口类型:互亿无线触发短信接口,支持发送验证码短信、订单通知短信等。//账户注册:请通过该地址开通账户http://user.ihuyi.c...

weixin_39758494 阅读(761)

python第三章作业_Python 第一~三章

第一章 初识Python这一章主要介绍了什么是Python、Python的安装、Python自带的一个集成开发环境IDEL及Anaconda平台,一、关于Python1、Python是一...

weixin_39968490 阅读(248)

浅析:私有属性和私有方法

#面向对象:#1.封装#2.继承#3.多态(了解)#4.抽象#1.封装:#封装了属性和方法#通过私有属性和私有方法来控制访问权限:public,private#类classPerson:...

瑞Raymond 阅读(872)

maven无法使用localRepository

背景装好Maven,设置好了环境变量,配置好settings.xml。然后发现在idea中无论如何都不能工作,以下几种情况都出现过。Cannotresolve...

ghStk1 阅读(910)

目录树 删除 数据结构_挑战408系列——总体目录

这段时间有读者私信我说我把所有科目都写在一个专栏上,有点乱,而且更新的时候也是想更哪个科目就更新哪个科目,不好找想要的文章。因此,今天抽空完成一...

weixin_39893274 阅读(280)