C++线程基础使用方法

文章目录

      • **1. 什么是线程**
      • **2. C++ 中的线程库**
      • **3. 创建线程**
        • 基本用法
        • 使用 Lambda 表达式
        • 使用类成员函数
      • **4. 管理线程**
        • `join` 和 `detach`
        • 检查线程是否可加入
      • **5. 数据共享与同步**
        • 数据竞争问题
        • 使用互斥锁 (`std::mutex`)
        • 死锁与避免
      • **6. 条件变量**
      • **7. 线程间通信**
        • 使用 `std::future` 和 `std::promise`
      • **8. 总结**


C++ 中的线程是指程序中能够独立执行的一条控制流。线程允许在同一个进程中并发运行多个任务,从而提高程序的性能和响应性。C++11 标准引入了对线程的原生支持,通过 <thread> 标准库提供了一套工具来管理线程。


1. 什么是线程

线程是程序执行的基本单位,多个线程可以共享同一进程的资源(如内存、文件句柄等)。线程的使用场景包括:

  • 多任务并行处理(如同时处理用户输入和后台计算)。
  • 提高程序性能(利用多核 CPU)。
  • 异步操作(如非阻塞 I/O)。

2. C++ 中的线程库

C++ 标准库中的线程功能由头文件 <thread> 提供,主要包括:

  • std::thread:用于创建和管理线程。
  • std::mutex:用于线程同步,防止数据竞争。
  • std::condition_variable:用于线程间的条件通知。
  • std::futurestd::promise:用于线程间的结果传递。

3. 创建线程

基本用法
#include <iostream>
#include <thread>void task() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(task); // 创建并启动线程t.join();            // 等待线程完成return 0;
}

说明:

  • std::thread t(task):启动线程 t,执行函数 task
  • t.join():主线程等待子线程完成。如果没有调用 join()detach(),程序会报错。
使用 Lambda 表达式
#include <iostream>
#include <thread>int main() {std::thread t([] {std::cout << "Hello from Lambda thread!" << std::endl;});t.join();return 0;
}
使用类成员函数
#include <iostream>
#include <thread>class Task {
public:void operator()() const {std::cout << "Hello from class thread!" << std::endl;}
};int main() {Task task;std::thread t(task); // 使用类的调用运算符t.join();return 0;
}

4. 管理线程

joindetach
  • join():等待线程执行完成。线程执行完成前,主线程会被阻塞。
  • detach():将线程与主线程分离,线程在后台继续运行。分离的线程无法再被主线程管理。
std::thread t(task);
t.detach();  // t 独立运行
检查线程是否可加入
if (t.joinable()) {t.join();
}

5. 数据共享与同步

数据竞争问题

多个线程共享数据时,可能会发生数据竞争(多个线程同时访问和修改同一资源)。

#include <iostream>
#include <thread>int counter = 0;void increment() {for (int i = 0; i < 100000; ++i) {++counter;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter: " << counter << std::endl; // 结果可能不正确return 0;
}
使用互斥锁 (std::mutex)

互斥锁可以防止数据竞争。

#include <iostream>
#include <thread>
#include <mutex>int counter = 0;
std::mutex mtx;void increment() {for (int i = 0; i < 100000; ++i) {std::lock_guard<std::mutex> lock(mtx); // 自动管理锁++counter;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter: " << counter << std::endl; // 结果正确return 0;
}
死锁与避免

使用多个互斥锁时可能会发生死锁。可以使用 std::lock 同时锁定多个资源。

std::lock(mutex1, mutex2);

6. 条件变量

条件变量用于线程间的同步,使一个线程等待另一个线程的通知。

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void worker() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return ready; }); // 等待通知std::cout << "Worker is running!" << std::endl;
}int main() {std::thread t(worker);std::this_thread::sleep_for(std::chrono::seconds(1));{std::lock_guard<std::mutex> lock(mtx);ready = true;}cv.notify_one(); // 通知线程t.join();return 0;
}

7. 线程间通信

使用 std::futurestd::promise
  • std::promise:允许线程间传递值。
  • std::future:用于获取异步结果。
#include <iostream>
#include <thread>
#include <future>void compute(std::promise<int> p) {p.set_value(42); // 设置结果
}int main() {std::promise<int> p;std::future<int> f = p.get_future();std::thread t(compute, std::move(p));std::cout << "Result: " << f.get() << std::endl; // 获取结果t.join();return 0;
}

8. 总结

C++ 的线程功能强大,可以用于实现高效的多任务并行处理。然而,开发多线程程序需要注意以下几点:

  1. 数据同步:通过 std::mutex 或其他机制避免数据竞争。
  2. 死锁问题:小心使用多个锁,合理设计锁的顺序。
  3. 资源管理:使用智能指针和 std::lock_guard 等工具确保资源安全。

正确地使用线程可以极大地提升程序的性能,但也增加了程序的复杂性和调试难度。

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

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

相关文章

HBase 开发:使用Java操作HBase

1、实战简介 HBase和Hadoop一样&#xff0c;都是用Java进行开发的&#xff0c;本次实训我们就来学习如何使用Java编写代码来操作HBase数据库。 实验环境&#xff1a; hadoop-2.7 JDK8.0 HBase2.1.1 2、任务 1、第1关&#xff1a;创建表 package step1; import java.io.IOE…

vulhub之log4j

Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645) 漏洞简介 Apache Log4j是一个用于Java的日志记录库,其支持启动远程日志服务器。Apache Log4j 2.8.2之前的2.x版本中存在安全漏洞。攻击者可利用该漏洞执行任意代码。 Apache Log4j 在应用程序中添加日志记录最…

【视觉SLAM】2-三维空间刚体运动的数学表示

读书笔记&#xff1a;学习空间变换的三种数学表达形式。 文章目录 1. 旋转矩阵1.1 向量运算1.2 坐标系空间变换1.3 变换矩阵与齐次坐标 2. 旋转向量和欧拉角2.1 旋转向量2.2 欧拉角 3. 四元数 1. 旋转矩阵 1.1 向量运算 对于三维空间中的两个向量 a , b ∈ R 3 a,b \in \R^3 …

Ubuntu22.04基于ROS2-Humble安装moveit2教程(亲测)

一、安装ROS2-Humble 1、参考&#xff1a;Ubuntu22.04安装ROS2-humble-CSDN博客 2、确保安装完成 source /opt/ros/humble/setup.bash 方法一&#xff1a;二进制安装 sudo apt install ros-humble-moveit* 方法二&#xff1a;安装源码编译 一、卸载二进制安装包 sudo a…

一些常见网络安全术语

1、黑帽 为非法目的进行黑客攻击的人&#xff0c;通常是为了经济利益。他们进入安全网络以销毁&#xff0c;赎回&#xff0c;修改或窃取数据&#xff0c;或使网络无法用于授权用户。这个名字来源于这样一个事实&#xff1a;老式的黑白西部电影中的恶棍很容易被电影观众识别&…

ISCTF 2024 web

ISCTF 2024 web 小蓝鲨的冒险 源码&#xff1a; <?php error_reporting(0); highlight_file(__FILE__); $a "isctf2024"; $b $_GET["b"]; parse_str($b); echo "小蓝鲨开始闯关&#xff0c;你能帮助他拿到flag吗?<br>"; if ($a…

AIGC----生成对抗网络(GAN)如何推动AIGC的发展

AIGC: 生成对抗网络(GAN)如何推动AIGC的发展 前言 随着人工智能领域的迅猛发展&#xff0c;AI生成内容&#xff08;AIGC&#xff0c;AI Generated Content&#xff09;正成为创意产业和技术领域的重要组成部分。在AIGC的核心技术中&#xff0c;生成对抗网络&#xff08;GAN&am…

删除k8s 或者docker运行失败的脚本

vi delete_exited_containers.sh#!/bin/bash# 列出所有停止的容器并存储到数组 list_exited_containers() {echo -e "\nStopped containers:"containers()# 获取停止的容器信息并存入数组while IFS read -r line; docontainers("$line")done < <(do…

如何在MindMaster思维导图中制作PPT课件?

思维导图是一种利用色彩、图画、线条等图文并茂的形式&#xff0c;来帮助人们增强知识或者事件的记忆。因此&#xff0c;思维导图也被常用于教育领域&#xff0c;比如&#xff1a;教学课件、读书笔记、时间管理等等。那么&#xff0c;在MindMaster免费思维导图软件中&#xff0…

【unity小技巧】一些unity3D灯光的使用与渲染及性能优化方案

文章目录 天空盒反射配置太阳耀斑眩光烘培光照烘培光照时弹出错误&#xff0c;记得勾选模型下面的选择阴影项目配置光源模型模型shader的问题 全局光照混合光照模式混合照明模式减性照明模式Shadowmask照明模式间接烘焙照明模式 环境光遮罩灯光探针反射探针技术关闭反射探针可以…

Linux :进程间通信之管道

一、进程间通信 1.1 是什么和为什么 1、进程间通信是什么&#xff1f;&#xff1f; ——>两个或多个进程实现数据层面的交互&#xff0c;但是由于进程独立性的存在&#xff0c;导致通信的成本比较高。 2、既然通信成本高&#xff0c;那为什么还要通信呢&#xff1f;&…

“乐鑫组件注册表”简介

当启动一个新的开发项目时&#xff0c;开发者们通常会利用库和驱动程序等现有的代码资源。这种做法不仅节省时间&#xff0c;还简化了项目的维护工作。本文将深入探讨乐鑫组件注册表的概念及其核心理念&#xff0c;旨在指导您高效地使用和贡献组件。 概念解析 ESP-IDF 的架构…

ATmaga8单片机Pt100温度计源程序+Proteus仿真设计

目录 1、项目功能 2、仿真图 ​3、程序 资料下载地址&#xff1a;ATmaga8单片机Pt100温度计源程序Proteus仿真设计 1、项目功能 设计Pt100铂电阻测量温度的电路&#xff0c;温度测量范围是0-100摄氏度&#xff0c;要求LCD显示。画出电路图&#xff0c;标注元器件参数&am…

【代码pycharm】动手学深度学习v2-05 线性代数

课程链接-05 线性代数 可以先看完特定轴求和再去看p2 import torch xtorch.tensor([3.0]) ytorch.tensor([2.0]) #标量 print(1.标量只有一个元素&#xff1a;\n,xy,x*y,x/y,x**y) x2torch.arange(4) #向量 print(2.向量视为标量值组成的列表&#xff1a;\n,x2) print(3.访问张…

SpringBoot源码解析(四):解析应用参数args

SpringBoot源码系列文章 SpringBoot源码解析(一)&#xff1a;SpringApplication构造方法 SpringBoot源码解析(二)&#xff1a;引导上下文DefaultBootstrapContext SpringBoot源码解析(三)&#xff1a;启动开始阶段 SpringBoot源码解析(四)&#xff1a;解析应用参数args 目录…

ZSTD 内存泄漏问题

优质博文&#xff1a;IT-BLOG-CN Zstandard&#xff08;简称zstd&#xff09;是一种无损压缩算法&#xff0c;由Facebook开发并开源。它旨在提供高压缩比和高解压速度的平衡&#xff0c;适用于多种数据压缩需求。 特点 【1】高压缩比&#xff1a; zstd能够在保持较高压缩比的…

前端:HTML (学习笔记)【1】

一&#xff0c;网络编程的三大基石 1&#xff0c;URL &#xff08;1&#xff09;url —— 统一资源定位符&#xff1a; 网址——整个互联网中可以唯一且准确的确定一个资源的位置。 【项目外】 网址——https://www.baidu.com/ …

【C++动态规划】3148. 矩阵中的最大得分|1819

本文涉及知识点 C动态规划 LeetCode 3148. 矩阵中的最大得分 给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格&#xff08;不必相邻&#xff09;。从值为 c1 的单元格移动到值为 c2 的单元格的得…

STM32完全学习——使用标准库点亮LED

一、使用标准库建立工程 &#xff08;1&#xff09;首先我们在ST的网站上面&#xff0c;下载标准库 &#xff08;2&#xff09;将标准外设库加入到项目中 我们一般只会使用到红色标注的那个文件夹&#xff0c;我们一般也只会将这个文件夹导入到工程里面&#xff0c;其他的还有…

解决微信小程序自定义tabbar点击两次才能跳转

在每个页面的js文件下加上此代码&#xff0c;selected属性代表每一个页面的下标&#xff0c;在不同的js文件下&#xff0c;要对应不同的selected值 代码&#xff1a; onShow() { // 确保 TabBar 存在并且设置选中项 if (this.getTabBar && this.getTabBar()) { this.…