C++ 多线程的错误和如何避免(9)

有时候使用 std::atomic 比使用 mutexes 更高效

问题分析:使用多线程更新一些简单数据时,比如 int 型,bool 型等等,可以使用 std::atomic,这比 mutex 来得更为高效。

比如,我们一般这样用:

1
2
3
4
5
int counter;
....
mu.lock();
counter++;
mu.unlock();

现在,我们可以这样用,

1
2
3
std::atomic<int> counter;
...
counter++;

概念

原子操作:可以把原子操作理解为一种不需要用到互斥量加锁(无锁)技术的多线程编程方式

互斥量:多线程编程中保护共享数据

使用场合

原子操作:针对的一般都是一个变量,而不是一个代码段

互斥量:加锁一般针对一个代码段(几行代码)

 

std::atomic 是个类模板,用来封装某个类型的值,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <thread>
#include <atomic>
#include <iostream>
 
std::atomic<int> g_mycount;
 
void mythread()
{
    for (int i = 0; i < 10000000; i++)
    {
        g_mycount++;
    }
    return;
}
 
int main()
{
    std::thread myobj1(mythread);
    std::thread myobj2(mythread);
    myobj1.join();
    myobj2.join();
    std::cout << "两个线程执行完毕,最终的g_mycount的结果是: " << g_mycount << std::endl;
}

最后会打印出:两个线程执行完毕,最终的g_mycount的结果是: 20000000

如果不使用 std::atomic,即直接定义

1
int g_mycount = 0;

最后会打印出:两个线程执行完毕,最终的g_mycount的结果是: 10240079

注意:该结果是个随机值,因为两个线程读写值不受限制

另外,原子变量不可以这样定义,如下

1
auto atm_copy = atm;

我们需要使用 .load(),以原子方式读取 atomic 对象的值

1
auto atm_copy = atm.load();

  

posted @   strive-sun  阅读(102)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示