当前位置: 首页 > news >正文

C++多线程编程:深入剖析std::thread的使用方法

一、线程std::thread简介

std::thread是 C++11 中引入的一个库,用于实现多线程编程。它允许程序创建和管理线程,从而实现并发执行。std::thread#include<thread>头文件中声明,因此使用std::thread时需要包含#include<thread>头文件。

二、语法

2.1、构造函数

(1)默认构造函数:创建一个空的 thread 执行对象。

代码语言:C++

自动换行

AI代码解释

thread() _NOEXCEPT { // construct with no thread _Thr_set_null(_Thr); }

(2)初始化构造函数:创建std::thread执行对象,该thread对象可被joinable,新产生的线程会调用threadFun函数,该函 数的参数由args给出。

代码语言:C++

自动换行

AI代码解释

template<class Fn,class ... Args> explicit thread(Fn&& fn,Args&& ... args);

&&表示既可以传入左值也可以传入右值。

(3)拷贝构造函数。

代码语言:C++

自动换行

AI代码解释

// 如果拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。 thread(const thread&) = delete;

(4)move构造函数 。

代码语言:C++

自动换行

AI代码解释

thread(thread&& x)noexcept

move构造函数,调用成功之后x不代表任何thread执行对象。注意:可被joinablethread对象必须在他们销毁之前被主线程join或者将其设置为detached

示例:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; void thread_func(int &a) { cout << "thread_func: a = " << (a += 10) << endl; } int main() { int x = 10; thread t1(thread_func, ref(x)); thread t2(move(t1)); // t1 线程失去所有权 thread t3; t3 = move(t2); // t2 线程失去所有权 // t1.join(); //执行会报错:已放弃 (核心已转储) t3.join(); cout << "main end: x = " << x << endl; return 0; }

执行结果:

代码语言:Bash

自动换行

AI代码解释

thread_func: a = 20 main end: x = 20

2.2、主要成员函数

(1)get_id():获取线程ID,返回类型std::thread::id对象。(2)joinable():判断线程是否可以加入等待。(3)join():等该线程执行完成后才返回。(4)detach()detach调用之后,目标线程就成为了守护线程,驻留后台运行,与之关联的std::thread对象失去对目标线程的关联,无法再通过std::thread对象取得该线程的控制权。当线程主函数执行完之后,线程就结束了,运行时库负责清理与该线程相关的资源。

调用 detach 函数之后:

  1. *this不再代表任何的线程执行实例。

  2. joinable() == false

  3. get_id() == std::thread::id()

三、简单线程的创建

使用std::thread创建线程,提供线程函数或者函数对象,并可以同时指定线程函数的参数。

  1. 传入0个值

  2. 传入2个值

  3. 传入引用

  4. 传入类函数

  5. detach

  6. move

(1)传入0个值:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; void thread_func1() { cout << "thread_func1()" << endl; } int main() { thread t1(&thread_func1); // 只传递函数 t1.join(); // 阻塞等待线程函数执行结束 return 0; }

(2)传入2个值:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; void thread_func2(int a, int b) { cout << "thread_func2(): a + b =" << a + b << endl; } int main() { int a = 10; int b = 16; thread t2(thread_func2, a, b); t2.join(); return 0; }

(3)传入引用:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; void thread_func3(int &c) { cout << "thread_func3(): &c = " << &c cout << " --> c + 10 =" << (c += 10) << endl; } int main() { int c = 10; thread t3(thread_func3, ref(c)); t3.join(); cout << "main --> 3 : &c = " << &c << ", c = " << c << endl; return 0; }

(4)传入类函数:

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; class A { public: void func4(int a) { cout << "thread:" << name_ << ", fun4 a = " << a << endl; } void setName(string name) { name_ = name; } void displayName() { cout << "this:" << this << ", name:" << name_ << endl; } void play() { std::cout << "play call!" << std::endl; } private: string name_; }; int main() { cout << "test--------------------------" << endl; A *a_ptr = new A(); a_ptr->setName("hello,C++11"); thread t4(A::func4, a_ptr, 10); t4.join(); delete a_ptr; A *a_ptr2 = new A(); a_ptr2->setName("hello,C++14"); thread t42(&A::func4, a_ptr2, 10);// 传入类的函数地址、类地址、参数 t42.join(); delete a_ptr; return 0; }

最好使用取地址符&的方式传入类函数,避免兼容问题。

(5)detach() :将子线程从主线程中分离出来,主线程不再具有管理此子线程的能力。

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; void thread_func5() { cout << "func5 into sleep " << endl; this_thread::sleep_for(chrono::seconds(2)); cout << "func5 leave " << endl; } int main() { thread t5(&thread_func5); t5.detach(); // t5.join() // 抛出异常 cout << "t5 id : " << t5.get_id() << endl; // 抛出异常 cout << "t5 joinable: " << t5.joinable() << endl; return 0; }

执行结果:

代码语言:Bash

自动换行

AI代码解释

t5 id : thread::id of a non-executing thread t5 joinable: 0

(6)std::move() :线程所有权转移。

展开

代码语言:C++

自动换行

AI代码解释

#include <iostream> #include <thread> using namespace std; int main() { thread t6(func6); thread t7(move(t6)); //t6.join(); // 抛出异常 cout << "t6 id : " << t6.get_id() << endl; cout << "t6 joinable: " << t6.joinable() << endl; cout << "t7 joinable: " << t7.joinable() << endl; t7.join(); return 0; }

执行结果:

代码语言:Bash

自动换行

AI代码解释

t6 id : thread::id of a non-executing thread t6 joinable: 0 t7 joinable: 1 this is func6 !

四、线程封装

封装线程,子类能继承,然后子类能实现具体的业务逻辑。创建线程通过new来实现,参数列表和使用构造函数创建是一样的。


http://www.jsqmd.com/news/813358/

相关文章:

  • 伺服系统高频啸叫故障排查:从机械共振到控制回路不稳定的诊断历程
  • 告别内存泄漏和数组越界:用CppCheck给你的C++项目做一次免费‘体检’
  • HS2-HF_Patch:Honey Select 2游戏增强补丁完整指南
  • 国产多模态大模型“刘知远”:技术原理、实战应用与未来展望
  • 量子计算连续门集:原理、实现与优化
  • 嵌入式系统自校准与自适应设计:从硬件映射到软件智能的实现
  • DAC 2013奥斯汀会议数据解读:技术会议选址如何影响参会质量与行业生态
  • AI Helpers:基于Kubernetes的AI/ML模型部署自动化工具集
  • PPT加密:保护PPT文件安全的两种加密方法
  • Claude Code Session 实战指南:AI 结对编程效能提升手册
  • 微信小程序 车牌号输入组件:从交互设计到代码实现的完整指南
  • 从TTP223到JL523:低成本电容触摸按钮的选型与实战
  • 2026年知名的精工装修施工/南充精工施工本地公司推荐 - 品牌宣传支持者
  • 基于LLM与OpenClaw的智能自动化:构建自然语言驱动的桌面脚本生成器
  • 把旧笔记本变成第二台电脑的“上网卡”:Win10/11网络共享实战指南
  • ChatGPT角色扮演调教指南:从提示词设计到沉浸式AI阿罗娜构建
  • LeetCode 287. 寻找重复数
  • 2026年口碑好的青岛镀锌风管/青岛除尘风管/青岛排烟风管/青岛角钢法兰风管优质厂家推荐榜 - 行业平台推荐
  • 2026年专业耐高温白钢管/201白钢管优质厂家汇总推荐 - 品牌宣传支持者
  • PX4开发环境搭建后,你的QGroundControl和MAVROS连接对了吗?
  • 如何快速实现语音转文字:AsrTools 零配置音频转字幕工具指南
  • Vinci智能助手视觉语言模型与跨视角检索技术解析
  • C++终端游戏开发:数据结构与算法在像素冒险世界中的应用
  • 从零到一:基于CASA模型的NPP估算实战指南
  • 告别catkin_make!ROS2 Foxy下用colcon编译你的第一个工作空间(附VSCode配置)
  • 国产多模态大模型部署利器:深度解析陈天奇技术栈
  • Linux Reactor网络模型与高效http静态服务器构建
  • 2026年口碑好的排烟风管/青岛除尘风管/青岛排烟风管/青岛镀锌风管高口碑品牌推荐 - 品牌宣传支持者
  • 2026进口艺术涂料哪个品牌好?进口艺术漆十大品牌厂家权威推荐 - 栗子测评
  • 基于CrewAI与RAG架构的法律智能体系统:从原理到落地实践