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 函数,等待所有线程执行完毕

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

相关文章
|
8月前
std::atomic和std::mutex区别
模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>。在多线程调用下,利用std::atomic可实现数据结构的无锁设计。
|
6天前
|
存储 C语言 C++
std::atomic 相关接口(来自cppreference.com)
std::atomic 相关接口(来自cppreference.com)
26 0
|
10月前
|
编译器
unsigned long int 和 unsigned long一样吗?
unsigned 代表的是无符号的整形数
163 0
|
安全 前端开发 Java
Unsafe 和 Atomic 详解(上)
在JDK 5之后,Java类库中才开始使用CAS操作,该操作由sun.misc.Unsafe类里面的 compareAndSwapInt()和compareAndSwapLong()等几个方法包装提供。HotSpot虚拟机在内部对这些方法做了特殊处理,即时编译出来的结果就是一条平台相关的处理器CAS指令,没有方法调用的过程, 或者可以认为是无条件内联进去了。
119 0
|
Java
Unsafe 和 Atomic 详解(下)
在JDK 5之后,Java类库中才开始使用CAS操作,该操作由sun.misc.Unsafe类里面的 compareAndSwapInt()和compareAndSwapLong()等几个方法包装提供。HotSpot虚拟机在内部对这些方法做了特殊处理,即时编译出来的结果就是一条平台相关的处理器CAS指令,没有方法调用的过程, 或者可以认为是无条件内联进去了。
82 0
int 与 unsigned int
cpp primer  P31 带符号类型和不带符号类型   1、除去布尔型和扩展字符外,其他整型可以划分为带符号的(signed)和无符号的(unsigned)两种。
1116 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]);...
1706 0
#define与typedef区别
1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。例如: #define PI 3.1415926 程序中的:area=PI*r*r 会替换为3.1415926*r*r 如果你把#define语句中的数字9 写成字母g 预处理也照样带入。
951 0