【C++入门到精通】C++ thread线程库 [ C++入门 ]

在这里插入图片描述

阅读导航

  • 引言
  • 一、thread类的简单介绍
  • 二、thread类的用法
    • 1. 创建线程
    • 2. 使用 Lambda 表达式
    • 3. 传递参数给线程
    • 4. 线程的 join 和 detach
    • 5. 检查线程是否可 join
    • 6. 线程的 ID
    • 7. 线程的移动语义
    • 8. 线程的析构
    • 🚨 注意事项
  • 三、线程函数参数
  • 温馨提示

引言

C++ thread线程库是C++11标准引入的一个强大工具,它提供了一种便捷的方式来创建和管理线程,使得并行编程变得更加容易和高效。这个库支持线程的创建、同步、互斥以及线程局部存储等功能。通过使用std::thread类,开发者可以轻松地创建新的线程来执行任务,并使用join()方法来等待线程完成。此外,线程库还包括了std::mutexstd::lock_guard等同步原语,以帮助管理线程间的资源访问,防止数据竞争和死锁。线程局部存储std::thread::idthread_local关键字则允许线程拥有自己的局部数据,这在多线程环境中非常有用。总的来说,C++ thread线程库为C++开发者提供了一个功能全面、易于使用的多线程编程解决方案。让我们一起开始这段关于thread线程库的学习之旅吧。

一、thread类的简单介绍

std::thread 类是C++11标准库中的一个核心组件,用于创建和管理独立的线程。它允许开发者通过传递一个函数或可调用对象来初始化线程,执行并行任务。线程对象的生命周期控制着线程的执行,而通过join()detach()方法,可以控制线程的同步和分离。此外,std::thread还提供了线程ID和状态检查功能,帮助开发者进行线程管理和异常处理,确保程序的稳定性和效率。
🚨注意:要使用线程库中的线程,必须包含<thread>头文件。线程类官方介绍文档

下面这个表格包含了 std::thread 类的构造函数、赋值运算符、比较运算符以及一些用于线程管理的成员函数。这些函数提供了创建、管理、比较和销毁线程的能力.

函数名功能描述
id get_id()返回线程的唯一标识符。
bool joinable()检查线程是否可 join,即是否还在运行。
void join()等待线程结束执行。
void detach()将线程与 std::thread 对象分离,使其在后台独立运行。
void swap(std::thread& other)与另一个 std::thread 对象交换线程。
thread::native_handle_type native_handle()返回线程的原生句柄,用于操作系统特定的线程操作。
bool operator==(const thread& other) const比较两个线程是否相同。
bool operator!=(const thread& other) const比较两个线程是否不同。
thread() noexcept默认构造函数,创建一个未关联线程的 std::thread 对象。
thread(nullptr_t) noexcept构造一个未关联线程的 std::thread 对象。
explicit thread(Callable&& func, Args&&… args)构造函数,创建一个线程并启动它来执行给定的可调用对象和参数。
thread(thread&& other) noexcept移动构造函数,获取另一个 std::thread 对象的所有权。
thread& operator=(thread&& other) noexcept移动赋值运算符,获取另一个 std::thread 对象的所有权。
~thread()析构函数,如果线程可 join,则会调用 join(),否则调用 detach()

二、thread类的用法

std::thread 类是 C++ 标准库中用于线程创建和管理的类。以下是 std::thread 类的一些关键用法和示例:

1. 创建线程

要创建一个线程,你需要实例化 std::thread 对象并传递一个函数或可调用对象(如 lambda 表达式或函数对象)作为参数。

#include <iostream>
#include <thread>void threadFunction() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(threadFunction);t.join(); // 等待线程结束return 0;
}

2. 使用 Lambda 表达式

Lambda 表达式提供了一种简洁的方式来定义匿名函数对象,非常适合用于线程。

#include <iostream>
#include <thread>int main() {std::thread t([]() {std::cout << "Hello from lambda thread!" << std::endl;});t.join();return 0;
}

3. 传递参数给线程

你可以将参数传递给线程函数。

void threadFunctionWithArgs(int x, double y) {std::cout << "x: " << x << ", y: " << y << std::endl;
}int main() {std::thread t(threadFunctionWithArgs, 10, 3.14);t.join();return 0;
}

4. 线程的 join 和 detach

  • join(): 调用此方法会阻塞,直到线程结束执行。
  • detach(): 调用此方法会使线程在后台继续运行,而不受 std::thread 对象的生命周期限制。
int main() {std::thread t([]() {// 线程执行的代码});t.detach(); // 线程现在在后台运行,不会等待它结束// 主线程继续执行,而 t 线程在后台运行return 0;
}

5. 检查线程是否可 join

在调用 join()detach() 之前,可以使用 joinable() 检查线程是否还在运行。

int main() {std::thread t([]() {// 线程执行的代码});if (t.joinable()) {t.join(); // 线程还在运行,等待结束}return 0;
}

6. 线程的 ID

每个线程都有一个唯一的 ID,可以使用 get_id() 获取。

int main() {std::thread t([]() {std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;});t.get_id(); // 获取线程 IDt.join();return 0;
}

7. 线程的移动语义

std::thread 对象可以被移动,但不能被复制。这意味着你可以通过移动语义来转移线程的所有权。

int main() {std::thread t1([]() {std::cout << "Thread 1 running" << std::endl;});std::thread t2 = std::move(t1); // t1 的所有权转移给 t2t2.join(); // 等待线程结束return 0;
}

8. 线程的析构

std::thread 对象被销毁时,如果线程是可 join 的,那么 join() 会被自动调用。如果线程已经被分离,则不会有任何操作。

{std::thread t([]() {// 线程执行的代码});// t 在这里离开作用域,自动调用 join()
} // t 的析构函数被调用

🚨 注意事项

  • 确保在 std::thread 对象生命周期结束前,线程已经被正确处理(join 或 detach)。
  • 避免在线程函数中调用 std::exit() 或者抛出未捕获的异常,因为这可能会导致程序的不稳定。
  • 使用互斥锁和条件变量来同步线程,避免数据竞争和死锁。

std::thread 提供了强大的工具来实现多线程编程,但也需要谨慎使用以确保程序的正确性和稳定性

三、线程函数参数

线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的,因此:即使线程参数为引用类型,在线程中修改后也不能修改外部实参,因为其实际引用的是线程栈中的拷贝,而不是外部实参

#include <thread>void ThreadFunc1(int& x) {x += 10; 
}void ThreadFunc2(int* x) {*x += 10; 
}int main() {int a = 10;// 在线程函数中对a修改,不会影响外部实参,因为:线程函数参数虽然是引用方式,但其实际引用的是线程栈中的拷贝    std::thread t1(ThreadFunc1, a);t1.join(); // 如果想要通过形参改变外部实参时,必须借助std::ref()函数std::thread t2(ThreadFunc1, std::ref(a));t2.join(); // 等待线程执行完成// 地址的拷贝std::thread t3(ThreadFunc2, &a);t3.join(); // 等待线程执行完成   return 0;
}

温馨提示

感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

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

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

相关文章

实现流程化办公,可以相信拖拽表单设计器!

当前&#xff0c;竞争压力越来越大&#xff0c;利用什么样优良的办公软件实现流程化办公&#xff1f;可以一起来了解低代码技术平台、拖拽表单设计器的优势特点&#xff0c;看看它们是如何助力企业降本、增效、提质的。低代码技术平台的优势特点多&#xff0c;可以助力企业用拖…

Uni app 开发支付宝小程序,保存到相册,获取小程序权限列表失败问题记录及解决方案。

第一种实现方案思路&#xff1a;先获取所有用户的权限列表配置&#xff0c;进行判断是否可以访问相册。 我在做的时候&#xff0c;在测试环境可以获取权限列表&#xff0c;但是在正式环境就会报错&#xff0c;报错原因是获取不到当前用户的权限列表用的这个方法&#xff08;uni…

Jtti:租用的php服务器运行异常是什么原因导致的?

PHP服务器运行异常可能由多种原因引起。以下是一些常见问题及其相应的解决方案&#xff1a; 1. 服务器资源不足 原因&#xff1a; CPU、内存或磁盘空间不足&#xff0c;导致服务器性能下降。 解决方案&#xff1a; 检查系统资源&#xff1a;使用以下命令检查CPU、内存和磁盘使用…

轻松实现微信内下载,Xinstall让你的App推广更高效!

在微信中推广App&#xff0c;你是否遇到过这样的困扰&#xff1a;推广链接被微信拦截&#xff0c;用户需要手动复制链接到浏览器才能下载&#xff0c;大大降低了安装率&#xff1f;今天&#xff0c;我们要介绍的Xinstall&#xff0c;就是一款能够解决这一痛点的神器&#xff01…

2.2 OpenCV随手简记(三)

图像的阈值处理定义 &#xff1a;将图像转化为二值图像&#xff08;黑白图&#xff09;, 也可以用于彩色图形&#xff0c;达到夸张的效果 目的&#xff1a;是用来提取图像中的目标物体&#xff0c;将背景和噪声区分开&#xff08;可以近似的认为除了目标全是噪声&#xff09;。…

掌握TypeScript的类型断言与守卫:提升代码灵活性与安全性

引言 TypeScript的类型系统为JavaScript带来了结构和严谨性&#xff0c;但有时我们需要更多的灵活性。类型断言和类型守卫是TypeScript提供的两个特性&#xff0c;它们允许我们在强类型的环境中进行更细致的类型操作。 基础知识 类型断言&#xff1a;一种明确告诉编译器某个…

GSEA的算法只考虑排序吗

其实这个问题很好回答&#xff0c;只需要运行如下代码&#xff0c;如下的基因列表是顺序是完全相同&#xff0c;并且我们只是做了最基础的变换 library(clusterProfiler) library(org.Hs.eg.db)data(geneList, package"DOSE")ego1 <- gseGO(geneList geneLi…

【iOS】UI学习(二)

UI学习&#xff08;二&#xff09; 进度条和滑动条步进器与分栏控件警告对话框和提示等待器UITextFieldUITextField控件UITextFieldDelegate协议 UIScrollView布局子视图手动布局子视图自动布局子视图 进度条和滑动条 下面通过一个程序来讲解该内容&#xff1a; #import <…

Django 里的增删改查

下面是步骤 先更新 urls.py 来添加新的url from django.contrib import admin from django.urls import path from app01 import viewsurlpatterns [path(demo/, views.demo), ]在 models.py 里创建表 from django.db import models# Create your models here. class UserI…

力扣 226. 翻转二叉树

给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/ struct TreeNode* invertTree(struct Tr…

[leetcode hot150]第五十七题,插入区间

题目&#xff1a; 给你一个 无重叠的 &#xff0c;按照区间起始端点排序的区间列表 intervals&#xff0c;其中 intervals[i] [starti, endi] 表示第 i 个区间的开始和结束&#xff0c;并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval [start, end] 表示…

62. UE5 RPG 近战攻击获取敌人并造成伤害

在上一篇&#xff0c;我们实现了通过AI行为树控制战士敌人靠近攻击目标触发近战攻击技能&#xff0c;并在蒙太奇动画中触发事件激活攻击的那一刻的伤害判断&#xff0c;在攻击时&#xff0c;我们绘制了一个测试球体&#xff0c;用于伤害范围。 在之前实现的火球术中&#xff0c…

HBuilderX打包uni-app项目成安卓app

目录 1、下载Android 离线SDK 2、Android Studio导入工程 3、生成签名 3.1、进入到jdk bin目录下&#xff0c;输入cmd执行命令keytool -genkey -alias wxsalias -keyalg RSA -keysize 2048 -validity 36500 -keystore wxs.keystore 生成签名 3.2、查看签名密钥keytool -lis…

Simulink从0搭建模型08-P9 While If SwitchCase模块的使用的使用

Simulink从0搭建模型08-P9 While & If & SwitchCase模块的使用的使用 今日学习内容1. While1.1. While Iterator Subsystem模块1.2. 样例11.3. 样例2 2. If2.1. if模块If Action Subsystem模块&#xff08;action) 3. Switch3.1. Switch Case模块3.2. If Action Subsys…

Java实战:文本文件复制

任务目标 本实战任务的目标是创建一个Java程序&#xff0c;用于复制指定的文本文件到另一个位置&#xff0c;并在控制台中显示复制结果。 任务步骤 创建源文件&#xff1a;在指定的路径D:\love.txt创建源文件。创建文件复制类&#xff1a;在net.huawei.student.test包中创建…

成功解决“ModuleNotFoundError: No Module Named Pycocotools”错误的全面指南

成功解决“ModuleNotFoundError: No Module Named Pycocotools”错误的全面指南 在Python的数据科学、计算机视觉和机器学习项目中&#xff0c;经常需要用到各种工具和库来加速开发过程。其中&#xff0c;pycocotools 是一个专门用于处理 COCO 数据集的库&#xff0c;它提供了多…

代理IP如何提高网站的SEO排名

目录 一、代理IP的作用 二、使用代理IP提高SEO排名的几种常见方法 1. 采集数据 2. 提交网站 3. 模拟用户行为 4. 搜索引擎优化 三、合理使用代理IP的注意事项 四、代码示例 总结 代理IP是一种可以隐藏真实IP地址的技术&#xff0c;通过使用代理IP&#xff0c;可以实现…

nuxt3采用传统scipt标签使用第3方库

背景&#xff1a; 我们经常需要使用到诸如swiper的第3方库&#xff0c;这种第3方库&#xff0c;有的提供相应的npm引入方式&#xff0c;有的没有&#xff0c;对于没有的&#xff0c;我们又想像传统web开发一样使用script引入&#xff0c;在nuxt3下面如何处理&#xff1f; 解决…

最大的游戏交流社区Steam服务器意外宕机 玩家服务受影响

易采游戏网6月3日消息&#xff1a;众多Steam游戏玩家报告称&#xff0c;他们无法访问Steam平台上的个人资料、好友列表和社区市场等服务。同时&#xff0c;社区的讨论功能也无法正常使用。经过第三方网站SteamDB的确认&#xff0c;&#xff0c;这一现象是由于Steam社区服务器突…

新奇css模板

引言 (csscoco.com)https://csscoco.com/inspiration/#/./init