atomic_int

简介: atomic_int

1.介绍

atomic_int 是一个原子类型,它可以在多线程环境中安全地进行读写操作,而不会出现数据竞争

可以把 atomic_int 想象成一个保险箱,多个人可以同时往里面存钱或取钱,但是每次只能有一个人操作,其他人必须等待。这样就可以保证每个人的操作都是安全的

2.例子

下面是一个简单的代码例子,演示了如何使用 atomic_int 来实现多线程安全的计数器:

#include <iostream>
#include <atomic>
#include <thread>
#include <vector>
std::atomic_int counter(0);
void increment(int n) {
    for (int i = 0; i < n; ++i) {
        ++counter;
    }
}
int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i) {
        threads.push_back(std::thread(increment, 1000));
    }
    for (auto& th : threads) {
        th.join();
    }
    std::cout << "Counter: " << counter << '\n';
    return 0;
}

这段代码创建了一个名为 counteratomic_int 类型的变量,它的初始值为0。increment 函数接受一个整数参数 n,表示需要对计数器进行递增的次数。在函数内部,有一个循环,每次循环都会对计数器进行递增操作。

main 函数中,首先创建了一个 threads 向量,用于存储线程对象。然后,使用循环创建了10个线程,每个线程都调用 increment 函数,并传入参数 1000,表示每个线程都需要对计数器进行1000次递增操作。

接下来,使用另一个循环等待所有线程执行完毕。最后,输出计数器的值。

由于计数器是一个 atomic_int 类型,所以每次递增操作都是原子的,不会出现数据竞争。因此,在所有线程执行完毕后,计数器的值应该为10000。

有人会对下面代码进行疑惑

for (auto& th : threads) {
        th.join();
    }

这段代码中的 for 循环用于等待所有线程执行完毕。join 函数会阻塞当前线程,直到被调用的线程执行完毕。在这个例子中,main 函数中的 for 循环会依次调用每个线程对象的 join 函数,等待所有线程执行完毕

这样做的目的是确保所有线程都完成了对计数器的递增操作,才输出计数器的最终值

相关文章
std::atomic和std::mutex区别
模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>。在多线程调用下,利用std::atomic可实现数据结构的无锁设计。
178 2
|
开发者
std::tuple还是struct?
std::tuple是C++11提供的新模板类,可以翻译为“元组”,可把多个不同类型的变量组合成一个对象。std::tuple可看做std::pair的泛化实现,std::pair包含两个元素,std::tuple 可以同时包含多个元素,它拥有 struct 的表现,但是无需定义实际的 struct,可用于一个函数返回多个值的场景下。
117 0
|
8月前
|
存储 C语言 C++
std::atomic 相关接口(来自cppreference.com)
std::atomic 相关接口(来自cppreference.com)
83 0
|
安全 Linux 开发工具
C++11 智能指针之shared_ptr<void>
基于Alexa的全链路智能语音SDK基于C++实现了跨平台特性,跑通了Android、Mac、Linux等设备,在兼容iOS时发现iOS未提供音频采集和播放的C++接口,所以需要改造SDK,允许SDK初始化时注入外部的采集器和播放器实现类,同时SDK中的Android播放器是基于ffmpeg解码 + opensl实现,但是考虑到包体积的问题,准备也基于这个接口在外部实现基于Android硬件解码的播放器。
579 0
std::map的KEY如果是char*,必须是malloc的
std::map的KEY如果是char*,必须是malloc的
122 0
|
安全 C++
boost1.53中的lock-free
boost1.53中的lock-free
514 0
int 与 unsigned int
cpp primer  P31 带符号类型和不带符号类型   1、除去布尔型和扩展字符外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。
1171 0
#define a int[10]与 typedef int a[10]用法
// #define a int[10] #include #include #define a int[10] int main() { int *p=(int *)malloc(sizeof(a)); p[0]=1; printf("%d\n",p[0]);...
1762 0
#define与typedef区别
1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。例如: #define PI 3.1415926 程序中的:area=PI*r*r 会替换为3.1415926*r*r 如果你把#define语句中的数字9 写成字母g 预处理也照样带入。
984 0