atomic 内存序_线程安全之std::atomic探索

本文介绍了C++11的std::atomic在多线程编程中的应用,通过实例展示了如何避免数据竞争。文章讨论了原子数据类型的原理,提供了不使用原子类型导致错误的示例,以及使用std::atomic修复问题的代码。同时,文章涵盖了不同内存序的使用,原子操作的常用成员函数,并提到了lock-free特性和read-modify-write操作。总结强调了std::atomic在多线程通信中的重要性。
摘要由CSDN通过智能技术生成

多线程的数据访问一直很让程序员们头大,有什么简便方法来实现多线程间的通呢?试试C++11封装的原子数据类型(std::atomic)吧。

17f4d4f6f3f8cf09efd233550e9687e4.png1
什么是原子数据类型

简单地说,原子数据类型能保证线程之间不会发生数据竞争(data race),因此能保证线程安全(thread safe)。

对于我们用户来说,就不需要对需要多线程访问的数据添加互斥锁。从不同线程访问某个原子对象是良性(well-defined) 行为,而通常对于非原子类型而言,并发访问某个对象(如果不做任何同步操作)会导致未定义(undefined) 行为发生。因此,从实现的原理上来,可以理解为原子类型在自己内部添加了互斥锁。

我们先创建一个CMake工程,并创建两个线程来操作同一个全局变量,然后来编译运行,查看它的结果。接下来,我们会针对这个结果进行改造,使之达到我们想要的“线程安全”的要求。2
测试环境
  • 系统:Ubuntu 16.04/18.04/20.04

  • 编程语言:C++

  • 测试代码:https://github.com/one-third-robot/article-003-atomic

e8182915c3b3ea70b3674b89271017fc.png

2
工程1:不使用原子数据类型

第一个工程,演示的是如果不使用原子数据类型,程序会产生一定的错误。工程代码可在以上GitHub链接中找到,工程文件名为no-atomic.cpp,内容如下:

#include 
#include
#include
#include
#include
int data( 0 );
void threadFunc() {
for ( int i = 0; i < 2000; i++ ) {
usleep( 1 );
data++;
}
}
int main( int argc, char* argv[] ) {
std::thread th1( threadFunc );
std::thread th2( threadFunc );
th1.join();
th2.join();
usleep( 20000 );
std::cout << "data = " << data << std::endl;
return 0;
}
  • 这里的data是一个全局变量(当然实际工程当中使用全局变量不是一个好的习惯,我们这里只是演示),初始值为0。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值