首页 > 编程语言 >最简单C++线程和互斥锁使用示例

最简单C++线程和互斥锁使用示例

时间:2024-09-10 15:50:41浏览次数:3  
标签:std thread 示例 C++ 互斥 mutex increment 线程

std::thread 是 C++11 标准库中引入的一个类,用于表示一个独立的执行线程。而 std::mutex 是 C++11 中提供的一种互斥锁,用于在多个线程间同步对共享数据的访问,以避免数据竞争和条件竞争。

下面将分别介绍 std::thread 和 std::mutex 的基本使用,并通过一个示例展示它们的结合使用。

std::thread 介绍

std::thread 用于创建一个新的线程,该线程执行指定的函数或可调用对象。其构造函数接受一个可调用对象(如函数指针、lambda 表达式、函数对象等)以及该可调用对象的参数。

示例代码:

#include <iostream>  
#include <thread>  
  
void hello() {  
    std::cout << "Hello from thread\n";  
}  
  
int main() {
    // 创建新线程,执行 hello 函数
    std::thread t(hello);  
  
    // 等待线程 t 执行完毕  
    t.join();  
  
    return 0;  
}

std::mutex 介绍

std::mutex 是一种互斥锁,它提供了一种机制来保护共享数据,使得同一时间只有一个线程可以访问被保护的资源。

示例:使用 std::thread 和 std::mutex

下面是一个使用 std::thread 和 std::mutex 的示例,其中两个线程尝试修改同一个共享变量,并使用 std::mutex 来确保每次只有一个线程可以修改该变量。

#include <iostream>  
#include <thread>  
#include <mutex>  
  
std::mutex g_mtx; // 创建一个互斥锁  
int g_counter = 0; // 共享变量  
  
void increment(int n) {  
    for (int i = 0; i < n; ++i) {
        // 自动加锁
        std::lock_guard<std::mutex> lock(g_mtx);
        ++g_counter;  
        // lock 在这里自动解锁  
    }  
}  
  
int main() {
    // 创建 t1、t2和t3 三个线程,执行 increment 函数,传递 1000 参数
    std::thread t1(increment, 1000);  
    std::thread t2(increment, 1000);  
    std::thread t3(increment, 1000);  
  
    // 等待线程 t1、t2和t3 执行完毕退出
    t1.join();  
    t2.join();
    t3.join();
  
    // 输出 g_counter 的值
    std::cout << "Counter: " << g_counter << std::endl;  
  
    return 0;  
}

在这个示例中,increment 函数被三个线程 t1、t2 和 t3 调用,每个线程尝试将 g_counter 增加 1000 次。使用 std::mutex 和 std::lock_guard 来确保在任何给定时间,只有一个线程可以修改 g_counter。std::lock_guard 是一个 RAII(Resource Acquisition Is Initialization)包装器,它自动在构造函数中加锁,在析构函数中解锁,从而简化了锁的管理。

注意事项

在实际编程中,应尽可能减少锁的粒度,以减少锁竞争和提高程序的性能。同时,也要避免死锁和活锁等问题。

-End-

#想了解更多精彩内容,关注下方公众号。

本人小杨哥:

超20年C++开发经验,独立软件开发;著名开源产品高并发C++应用服务器MYCP作者;开源企业即时通讯软件Entboost首席架构师;开发有WordBN字远笔记等共享软件产品。

标签:std,thread,示例,C++,互斥,mutex,increment,线程
From: https://blog.csdn.net/yanghz/article/details/141992866

相关文章

  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【回溯】2024E-字符串
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路代码pythonjavacpp时空复杂度华为OD算法/大厂面......
  • 【C++】priority_queue讲解
    一、priority_queue的本质priority_queue的本质就是堆,添加的元素按照堆的规则存储,默认情况下是大堆。二、priority_queue的参数priority_queue有三个参数。intmain(){priority_queue<int,vector<int>,less<int>>s;//第一个参数为要存放的数据类型//第......
  • C++学习笔记(14)
    二、栈解旋异常被抛出后,从进入try语句块开始,到异常被抛出之前,这期间在栈上构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程称为栈的解旋。也就是在执行throw前,在try执行期间构造的所有对象被自动析构后,才会进入catch匹配。在堆上构造的对象肿......
  • C/C++面试
    文章目录第一章C++基本语法C++和C的区别为什么C++支持函数重载而C语言不支持呢include头文件双引号””和尖括号<>的区别头文件的作用是什么?在头文件中进行类的声明,在对应的实现文件中进行类的定义有什么意义?C++源文件从文本到可执行文件经历的过程静态链接与动态链接C......
  • C++:拷贝构造函数、赋值运算符重载
    目录一、拷贝构造函数拷贝构造的特点二、赋值运算符重载2.1运算符重载2.2赋值运算符重载赋值运算符重载的特点一、拷贝构造函数  如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数,也就是说拷贝构造是......
  • C++的数据类型----标准库类型(std::vector容器/std::list容器/std::map容器)的实例讲解
    目录1.字符串(std::string):用于处理文本字符串。2.容器:如std::vector、std::list、std::map等,用于存储和管理数据集合2.1std::vector容器2.2std::list容器2.3std::map容器1.字符串(std::string):用于处理文本字符串。下面是一个C++中字符串的示例程序......
  • Ignite系列1-jdbc连接,建表,查询示例
    一、JDBC方式连接Ignite集群    通过JDBC方式连接Ignite集群,执行SQL进行见表,mergeinto插入数据,并执行结果查询示例如下:/***测试ignitejdbc连接,简单创建按一张表,插入一条数据,然后查询出来,并验证字段是否正确*@throwsClassNotFoundException*......
  • 【C/C++】“秒懂”学C/C++不可错过的“经典编程题” — 日期类的经典运用 (含题链接)
    “秒懂”学C/C++不可错过的“经典编程题”—日期类的经典运用(含题链接)1.计算日期到天数转换(1).解题思路:(2).代码实现:2.打印日期(1).解题思路:(2).代码实现:3.日期累加(1).解题思路:(2).代码实现:4.日期差值(1).解题思路:(2).代码实现:1.计算日期到天......
  • QT简易右键菜单示例
    widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QMenu>classWidget:publicQWidget{Q_OBJECTpublic:Widget(QWidget*parent=nullptr);~Widget();private:voidcontextMenuEvent(QContextMenuEvent*event)overri......
  • 7种提示词应用技巧:细节法、分解法、投票法、示例法、角色法、反思法、记忆法
    找到好的prompt是个持续迭代的过程,需要不断调优。善于使用方法,才能事半功倍。细节法:就像你做饭时,要记得放多少盐、多少水一样,细节法就是让我们在解决问题时,注意到每一个小步骤和小事情,这样我们就不会漏掉重要的信息。分解法:这个方法就像把一个大苹果切成小块,这样吃的时候更容易......