首页 > 编程语言 >C++多线程不加锁操作同一个整数

C++多线程不加锁操作同一个整数

时间:2023-08-11 14:57:53浏览次数:45  
标签:加锁 int 多线程 C++ num volatile include

#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <atomic>
using namespace std;

int num = 0;
//volatile int num = 0;
//atomic<int> num = 0;
void add()
{
    int times = 0;
    for (int i = 0; i < 10000; ++i)
    {
        //std::cout << std::this_thread::get_id() << ":" << num++ << std::endl;
        num++;
        this_thread::sleep_for(chrono::milliseconds(0));
        times++;
    }
    std::cout << "thread id: [" << std::this_thread::get_id() << "] run times:" << times << std::endl;
}
int main()
{
    vector<thread> vects;
    for (int i = 0; i < 2; ++i)
    {
        vects.push_back(thread(add));
    }
    for (auto& t : vects)
    {
        t.join();
    }
    std::cout << "main thread, final num: " << num << std::endl;
}

上面是两线程同时对num执行自加操作, 实际输出结果:

thread id: [29524] run times:10000
thread id: [30444] run times:10000
main thread, final num: 17766

两个结程每个线程执行对同一个数连加10000次,  加锁或使用atomic的值应该是20000. 

网上有说单个数值可以不用加锁的原因是, 单条cpu指令取这个整数值是不会出错的. 他们推荐类对象或struct要加锁, 比如struct strTest{int a, int b}, 取strTest数据, 需要两条指令才能完成, 先取a值, 再取b值, 多线程时会有其它指令在中间正好修改了b值.

volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改。volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。

标签:加锁,int,多线程,C++,num,volatile,include
From: https://www.cnblogs.com/barrysgy/p/17622953.html

相关文章

  • VS2019 C++ 调用python函数/类对象的方法
    1.环境配置VS工程配置要和python一致,安装的python如果是64位的,工程配置也要选成64位的在工程配置中添加包含目录和库目录,添加python环境目录里的include和libs文件夹路径。想要运行的keras-yolo3是在Anaconda中配置的环境,所以相应的文件夹路径可以在Anaconda的环境文件中......
  • 软件开发入门教程网 Search之C++ 动态内存
       C++基本的输入输出   ......
  • 软件开发入门教程网 Search之C++ 环境设置
       C++基本的输入输出   ......
  • C++ Boost库简介
    1、boost是一个功能强大、构造精良、跨平台、代码开源、完全免费的c++程序库。1)功能强大:共包含160余个库/组件,涵盖字符串与文本处理、容器、迭代器、算法、图像处理、模板元编程、并发编程等多个领域。2)构造精良: 由c++标准委员会成员发起倡议并建立boost社区,C+......
  • C++ Boost库介绍
    Boost库是C++的一个开源类库,包含了大量实用工具和组件,可以大大简化C++编程过程中的繁琐操作。以下是Boost库常见的运用场景:1.多线程编程:Boost.Thread模块提供了丰富的线程相关功能,如锁、条件变量、线程池等,使得多线程编程更加容易。2.正则表达式处理:Boost.Regex模块提供了对正......
  • C++ 构造函数初始化:提高代码可读性和执行效率
    在C++中,构造函数是用来初始化对象数据成员的。一个对象在创建的时候,构造函数会被自动调用,以便为该对象的数据成员赋初值。传统的初始化方式是在构造函数内部对数据成员逐一进行初始化,这种方式虽然可行,但是代码复杂度高且效率低下。本文将介绍如何使用构造函数初始化列表来提高......
  • C/C++住院病人管理系统[2023-08-11]
    C/C++住院病人管理系统[2023-08-11]22、住院病人管理系统(难度等级8)使用C或C++,选择一种计算机编程软件和数据库管理系统来实现一个住院病人管理系统。系统需要实现的功能如下:(1)添加、删除和修改病人信息:向系统中添加、删除和修改仓库信息,信息包括(住院号、姓名、年龄、住院时间、......
  • C++ 初学者如何正确使用指针
    一、指针的基本概念指针是C++中非常重要的概念,也是初学者经常会遇到的问题。指针是一个存储变量地址的变量,它指向存储器中的一个地址。使用指针可以直接操作存储器中的数据,因此常用于处理复杂的数据结构和算法。二、指针的定义和使用定义指针以及使用指针的步骤如下:1......
  • C++ 字符串拼接技巧(stringstream、字符串迭代器、字符串的加法运算符、std::accumulat
    在C++中,经常需要将多个字符串拼接成一个大字符串。这个过程很容易出错,但有一些技巧可以帮助我们轻松地实现这个目标。本文将介绍一些C++中join字符串的技巧。一、使用stringstreamstringstream是一个流。使用它可以将多个字符串连接起来,然后将它们转换为一个字符串。可......
  • C++高质量问答精选
    https://stackoverflow.com/questions/21204676/modern-way-to-filter-stl-containerhttps://stackoverflow.com/questions/4303513/push-back-vs-emplace-back......