详细介绍:C++中的thread

news/2026/1/20 20:53:07/文章来源:https://www.cnblogs.com/tlnshuju/p/19508795

详细介绍:C++中的thread

2026-01-20 20:51  tlnshuju  阅读(0)  评论(0)    收藏  举报

C++ 的多线程支持是从 C++11 标准开始引入的,标准库提供了 <thread> 头文件,使得多线程编程变得跨平台且更加简便。在此之前,开发者通常需要依赖操作系统特定的 API(如 Linux 的 pthreads 或 Windows 的 CreateThread)。

1. std::thread 的基础使用

要使用多线程,首先需要包含头文件:

#include 
创建与启动线程

std::thread 对象一旦创建,线程就会立即开始执行。你可以传递函数指针Lambda 表达式或**函数对象(Functor)**作为线程的入口。

#include 
#include 
void worker(int n) {std::cout << "Thread " << n << " is running." << std::endl;
}
int main() {// 创建一个线程 t1,执行 worker 函数,传入参数 1std::thread t1(worker, 1);// 使用 Lambda 表达式创建线程std::thread t2([](){std::cout << "Lambda thread is running." << std::endl;});// 等待线程结束(必须操作,否则程序退出时会崩溃)t1.join();t2.join();std::cout << "Main thread finished." << std::endl;return 0;
}

2. 核心成员函数:joindetach

创建线程后,必须决定主线程(或父线程)如何处理这个新线程。这是多线程编程中最基本也是最重要的步骤。

函数

描述

比喻

join

阻塞等待。主线程停下来,等待子线程执行完毕后,汇合(join)到一起,然后再继续执行。

父母等孩子:父母(主线程)必须等孩子(子线程)吃完饭,大家才能一起离席。

detach

分离运行。子线程与主线程断开联系,在后台独立运行。主线程结束也不影响子线程(除非整个进程结束)。

放风筝断线:风筝(子线程)飞走了,父母(主线程)不再管它,它自己飞直到落地(执行完)。

joinable

检查线程是否可以被 join

detach

。如果一个线程已经被 join

过或 detach

过,它就不再是 joinable 的。

检查孩子是否还在饭桌上。

注意: 如果 std::thread 对象在销毁前(例如离开作用域)没有调用 join() 也没有调用 detach(),程序会调用 std::terminate() 导致崩溃。


3. 线程传参:值拷贝 vs 引用

这是 C++ 多线程编程中极易出错的地方。

  • 默认行为:std::thread 构造函数会拷贝所有的参数到线程的独立内存空间中。
  • 传递引用: 如果你想在线程中修改外部变量,或者为了性能不想拷贝(例如大对象),必须使用 std::ref() 显式包装引用。
#include 
#include 
void updateValue(int& n) {n += 10;
}
int main() {int val = 0;// 错误用法:std::thread t(updateValue, val); // 编译报错,或者产生拷贝导致 val 不变// 正确用法:使用 std::refstd::thread t(updateValue, std::ref(val));t.join();std::cout << "Value is: " << val << std::endl; // 输出 10return 0;
}

4. 线程同步与数据竞争 (Synchronization)

当多个线程同时访问同一个变量(且至少有一个是写操作)时,就会发生数据竞争 (Data Race),导致结果不可预测。

为了解决这个问题,我们需要使用互斥锁 (Mutex)

A. 互斥量 (std::mutex)

位于 <mutex> 头文件中。

  • lock(): 上锁。如果已被锁,则阻塞等待。
  • unlock(): 解锁。
B. RAII 锁管理 (std::lock_guardstd::unique_lock)

强烈建议不要直接手动调用 lock()unlock(),因为如果中间抛出异常或忘记解锁,会导致死锁 (Deadlock)。应该使用 RAII 风格的封装类。

  • std::lock_guard: 最简单,构造时上锁,析构时(作用域结束)自动解锁。不可手动解锁。
  • std::unique_lock: 更灵活,可以手动 lock/unlock,可以延迟锁定,通常配合条件变量使用。
#include 
#include 
#include 
#include 
int shared_counter = 0;
std::mutex mtx; // 全局互斥锁
void increase() {for (int i = 0; i < 1000; ++i) {// 进入作用域自动上锁std::lock_guard lock(mtx);// 临界区 (Critical Section)shared_counter++;// 离开作用域,lock 自动析构并解锁}
}
int main() {std::vector threads;for(int i=0; i<10; ++i) {threads.emplace_back(increase);}for(auto& t : threads) t.join();std::cout << "Final counter: " << shared_counter << std::endl; // 必定是 10000return 0;
}

5. 进阶:原子操作 (std::atomic)

对于简单的变量(如 int, bool)的自增、自减或状态标记,使用互斥锁太重了(开销大)。C++ 提供了 <atomic>

std::atomic 保证了对变量的操作是原子的(不可分割),无需加锁,性能更高。

#include 
std::atomic atom_counter(0); // 定义原子整型
void fastIncrease() {for (int i = 0; i < 1000; ++i) {atom_counter++; // 这一步是原子的,线程安全}
}

6. 多线程编程的常见陷阱

  1. 死锁 (Deadlock)
    • 场景:线程 A 持有锁 1 等待锁 2,线程 B 持有锁 2 等待锁 1。两者互相等待,永久卡死。
    • 解决:保证所有线程以相同的顺序获取锁;或者使用std::lock(mtx1, mtx2) 同时锁定多个互斥量。
  1. 悬空引用 (Dangling Reference)
    • 场景:你在函数中创建了一个线程,并传递了一个局部变量的引用给它。然后使用了 detach()--->主线程和子线程分离。
    • 后果:如果主函数先结束,局部变量被销毁,但子线程还在运行并试图访问那个已经被销毁的变量 -> 崩溃
  1. 虚假唤醒 (Spurious Wakeup)
    • 在使用 std::condition_variable(条件变量)等待信号时,线程可能会在没有收到信号的情况下醒来。因此,wait 必须放在 while 循环中检查条件,而不是 if

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1190741.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第7天敏捷冲刺日志

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13474昨日完成:bug修…

第4天敏捷冲刺日志

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13474昨日完成:房间创…

paperxie 期刊论文:从选题到见刊,智能工具让学术发表不再是 “玄学”

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/aippt https://www.paperxie.cn/ai/journalArticleshttps://www.paperxie.cn/ai/journalArticleshttps://www.paperxie.cn/ai/journalArticles 对于科研人来说&#xff0c;一篇期刊论文的发表&#xff0c;…

第3天敏捷冲刺日志

昨日完成: 用户登录验证逻辑 -词库表结构设计 今日计划: 实现“房间创建”与“加入房间”功能(含唯一房间ID生成) 联调数据库插入与查重逻辑 问题挑战: 房间ID防重复机制设计略复杂,采用“时间戳+随机字符串”生…

【性能测试】13_JMeter _JMeter分布式

文章目录一、分布式1.1 为什么使用分布式1.2 什么是分布式1.3 分布式原理二、分布式配置2.1 代理机&#xff08;Agent&#xff09;配置2.2 控制机&#xff08;Controller&#xff09;配置三、实施案例3.1 搭建目录结构3.2 执行机和控制机配置3.3 执行机和控制机启动四、注意事项…

paperxie 毕业论文:本科通关神器,3000 字原创轻松交付[特殊字符]

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/aippt https://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertation 还在对着空白文档发愁&#xff1f;本科毕业论文的 DDL 步步紧逼&#…

第5天敏捷冲刺日志

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13474昨日完成:AI联想…

经典卷积神经网络简单介绍

AlexNet:它由五个卷积层,三个最大池化层,两个全连接隐藏层和一个全连接输出层组成,采用ReLu作为激活函数,在训练过程中引入dropout增强模型泛化能力,在2012年ImageNet图像大赛上大放异彩,历史意义极其重要,它的…

Java SaaS Niucloud云编译全端开发框架:革新企业级应用开发模式

摘要随着企业数字化转型的加速&#xff0c;构建高效、灵活且可扩展的软件系统成为关键需求。Java SaaS Niucloud云编译全端开发框架应运而生&#xff0c;它是一款集插件化架构、云安装、云编译与云发布功能于一体的快速开发SaaS多用户系统后台管理框架。本文深入探讨了Niucloud…

实验 2 Scala 编程初级实践

// 在 spark-shell 提示符下直接粘贴即可 import scala.io.StdInval q = StdIn.readLine("请输入 q: ").trim.toDoublevar n = 1 var sn = 0.0 var term = 0.0while (sn < q) {term = (n + 1).toDoubl…

【收藏必备】Transformer架构深度解析:一文掌握大模型核心原理

Transformer通过自注意力(QKV)和多头注意力机制实现高效长距离依赖捕捉&#xff0c;结合残差连接和层归一化保障训练稳定性&#xff0c;彻底解决传统RNN/CNN的顺序处理限制&#xff0c;实现并行计算&#xff0c;成为大模型的核心架构。本文系统解析其组件和工作原理&#xff0c…

解锁AI生产力新境界:Coze平台200+工作流合集深度解析与实战指南

摘要&#xff1a;本文开源分享了一套覆盖200实用场景的Coze工作流合集&#xff0c;从项目背景、技术价值到详细操作指南&#xff0c;系统性解析如何通过标准化工作流实现AI任务自动化。通过Git克隆或ZIP下载两种方式&#xff0c;读者可快速获取并导入工作流至Coze平台&#xff…

paperxie 毕业论文写作工具:本科生通关毕业季的秘密武器

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/aippt https://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertationhttps://www.paperxie.cn/ai/dissertation 毕业季的钟声已经敲响&#xff0c;当你还在为本科毕业论文焦头烂额时&…

人群仿真软件:Legion_(5).Legion建模工具使用

Legion建模工具使用 1. 建模工具概述 Legion建模工具是Legion软件的核心组成部分之一&#xff0c;用于创建和编辑人群仿真模型。该工具提供了丰富的功能和工具集&#xff0c;使得用户能够高效地构建复杂的仿真环境。建模工具的主要功能包括&#xff1a;几何建模&#xff1a;创建…

救命神器8个AI论文网站,继续教育学生轻松搞定毕业论文!

救命神器8个AI论文网站&#xff0c;继续教育学生轻松搞定毕业论文&#xff01; AI 工具如何助力论文写作&#xff1f; 在当今快节奏的学习环境中&#xff0c;继续教育学生面临着越来越大的学术压力&#xff0c;尤其是毕业论文的撰写。传统的写作方式不仅耗时耗力&#xff0c;还…

Python语法进阶笔记(五)

一、可迭代对象可迭代对象Iterable遍历&#xff08;迭代&#xff09;&#xff1a;依次从对象中把一个个元素取出来的过程数据类型&#xff1a;str、list、tuple、dict、set等可迭代对象的条件对象实现了_ _ iter _ _ () 方法_ _iter _ _() 返回了迭代器对象for 循环工作原理先通…

第二篇冲刺博客

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/Class12Grade23ComputerScience/homework/13474第2天敏捷冲刺日…

Python语法进阶笔记(五)

一、可迭代对象可迭代对象Iterable遍历&#xff08;迭代&#xff09;&#xff1a;依次从对象中把一个个元素取出来的过程数据类型&#xff1a;str、list、tuple、dict、set等可迭代对象的条件对象实现了_ _ iter _ _ () 方法_ _iter _ _() 返回了迭代器对象for 循环工作原理先通…

struts2 命令执行 (CVE-2016-3081)

直接使用工具跑存在漏洞,直接执行命令