一:概述

  项目中经常用遇到多线程操作共享数据问题,常用的处理方式是对共享数据进行加锁,如果多线程操作共享变量也同样采用这种方式。

  为什么要对共享变量加锁或使用原子操作?如两个线程操作同一变量过程中,一个线程执行过程中可能被内核临时挂起,这就是线程切换,当内核再次切换到该线程时,之前的数据可能已被修改,不能保证原子操作。

  C++11提供了个原子的类和方法atomic,保证了多线程对变量原子性操作,相比加锁机制mutex.lock(),mutex.unlock(),性能有几倍的提升。

  所需头文件<atomic>

二:错误代码
//全局变量 int g_num = 0; void fun() { for (int i = 0; i < 10000000; i++) {
g_num++; } return ; } int main() { //创建线程1 thread t1(fun); //创建线程2 thread
t2(fun); t1.join(); t2.join(); cout << g_num << endl; getchar(); return 1; }
应该输出结果20000000,实际每次结果都不一样,总是小于该值,正是由于多线程操作同一变量而没有保证原子性导致的。

三:加锁代码
//全局变量 int g_num = 0; mutex m_mutex; void fun() { for (int i = 0; i <
10000000; i++) { m_mutex.lock(); g_num++; m_mutex.unlock(); } return ; } int
main() { //获取当前毫秒时间戳 typedef chrono::time_point<chrono::system_clock,
chrono::milliseconds> microClock_type; microClock_type tp1 =
chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
long long time1 = tp1.time_since_epoch().count(); //创建线程 thread t1(fun); thread
t2(fun); t1.join(); t2.join(); cout << "总数:" << g_num << endl; //获取当前毫秒时间戳
microClock_type tp2 =
chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
long long time2 = tp2.time_since_epoch().count(); cout << "耗时:" << time2 -
time1 << "ms" << endl; getchar(); return 1; }
执行结果:多次测试输出均为20000000,耗时在3.8s左右

四:atomic原子操作代码
//全局变量 atomic<int> g_num = 0; void fun() { for (int i = 0; i < 10000000; i++)
{ g_num++; } return ; } int main() { //获取当前毫秒时间戳 typedef
chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type;
microClock_type tp1 =
chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
long long time1 = tp1.time_since_epoch().count(); //创建线程 thread t1(fun); thread
t2(fun); t1.join(); t2.join(); cout << "总数:" << g_num << endl; //获取当前毫秒时间戳
microClock_type tp2 =
chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
long long time2 = tp2.time_since_epoch().count(); cout << "耗时:" << time2 -
time1 << "ms" << endl; getchar(); return 1; }
执行结果:多次测试输出均为20000000,耗时在1.3s左右

五:总结

  c++11的原子类atomic相比使用加锁机制性能有2~3倍提升,对于共享变量能用原子类型的就不要再用加锁机制了。

 

技术
©2019-2020 Toolsou All rights reserved,
BugkuCTF-Web-计算器(随机数字运算验证码)(精华)2020年7月13日 微信小程序 页面间通信线上问题排查之HTTP状态码——415和406LED 滚动文字uboot设置nfs参数——linux kernel使用nfs方式加载根文件系统rootfs(六) 艾伟也谈项目管理,基层管理杂谈明明是post请求为什么会在地址栏显示参数?(精华)2020年8月9日 C#基础知识点 反射判断当前对象是不是数组的4种方式npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法