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

C++并发以及多线程的秘密

1.基础概念

并发(Concurrency)

并发是指在同一时间段内,多个任务看起来像是同时执行的。并发并不一定意味着真正的同时执行,它可以是通过时间片轮转等方式在多个任务之间快速切换,让用户感觉多个任务在同时进行。并发可以通过多线程、多进程等方式实现。

线程(Thread)

线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的内存空间和系统资源,但每个线程有自己独立的栈空间和执行上下文。线程之间的通信和数据共享比进程更加方便和高效。比如,在一个浏览器进程中,可能会有负责渲染页面的线程、处理网络请求的线程等。

多线程(Multithreading)

多线程是实现并发的一种方式,它允许一个进程中同时存在多个线程,这些线程可以并行(在多核 CPU 上)或并发(在单核 CPU 上)执行不同的任务,从而提高程序的执行效率和响应速度。

进程(Process)

进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有自己独立的内存空间、系统资源(如文件描述符等)和执行上下文。不同进程之间相互独立,一个进程的崩溃通常不会影响其他进程。例如,当你打开一个浏览器、一个文本编辑器时,它们分别对应着不同的进程。(一个进程有一个主线程)

2 .操作多线程

2.1 创造线程

在 C++ 中,<thread> 库提供了用于管理线程的类和函数,它是 C++11 标准引入的,用于支持多线程编程

默认构建:

std::thread t;

带执行函数的构造函数:创建一个新线程并执行指定的函数。可以传递参数给该函数

#include <iostream>
#include <thread>void func(int a) {std::cout << "线程执行,参数: " << a << std::endl;
}int main() {std::thread t(func, 42);t.join();  // 等待线程执行完毕return 0;
}

记得 线程只能出传入右值

右值引用与线程

#include <iostream>
#include <thread>
#include <string>// 线程函数,接受一个字符串参数
void threadFunction(std::string str) {std::cout << "线程接收到的字符串: " << str << std::endl;
}int main() {// 使用右值引用传递临时对象给线程std::thread t(threadFunction, std::string("Hello, Thread!"));// 等待线程执行完毕t.join();return 0;
}

左值引用与线程

左值引用用于引用一个已经存在的对象。在多线程编程中,如果需要在线程函数中修改外部对象,或者避免对象的拷贝,可以使用左值引用

#include <iostream>
#include <thread>
#include <string>// 线程函数,接受一个字符串的左值引用
void threadFunction(std::string& str) {str += " - Modified by thread";std::cout << "线程修改后的字符串: " << str << std::endl;
}int main() {std::string message = "Initial message";// 使用左值引用传递对象给线程std::thread t(threadFunction, std::ref(message));//ref提取地址// 等待线程执行完毕t.join();std::cout << "主线程看到的修改后的字符串: " << message << std::endl;return 0;
}

因为线程只能右值传递,所有以引用形式传递对象(值传递和引用之间的区别 你可以理解为复制和对地址操作)关于右值的话:c++新特性之 左右值 lambda 以及“for”-CSDN博客

成员函数

普通:

#include <iostream>
#include <thread>class MyClass {
public:// 普通成员函数void memberFunction(int value) {std::cout << "线程正在执行成员函数,传入的值是: " << value << std::endl;}
};int main() {MyClass obj;int param = 42;// 创建线程并引用类的普通成员函数std::thread t(&MyClass::memberFunction, &obj, param);// 等待线程执行完毕t.join();return 0;
}

静态:

#include <iostream>
#include <thread>class MyClass {
public:// 普通成员函数void memberFunction(int value) {std::cout << "线程正在执行成员函数,传入的值是: " << value << std::endl;}
};int main() {MyClass obj;int param = 42;// 创建线程并引用类的普通成员函数std::thread t(&MyClass::memberFunction, &obj, param);// 等待线程执行完毕t.join();return 0;
}

2.2成员函数

join函数

join() 函数的作用是阻塞当前线程,直到被调用 join() 的 std::thread 对象所代表的线程执行完毕。也就是说,当在一个线程(通常是主线程)中调用另一个线程对象的 join() 方法时,当前线程会暂停执行,等待目标线程执行结束后才会继续执行后续代码。

#include <iostream>
#include <thread>// 线程函数
void threadFunction() {for (int i = 0; i < 5; ++i) {std::cout << "子线程输出: " << i << std::endl;}
}int main() {std::thread t(threadFunction);std::cout << "主线程等待子线程执行完毕..." << std::endl;t.join();  // 主线程阻塞,等待子线程执行完毕std::cout << "子线程执行完毕,主线程继续执行。" << std::endl;return 0;
}

detch 函数

detach() 函数用于将 std::thread 对象所代表的线程与该对象分离,让线程在后台独立执行。分离后的线程在执行完毕后会自动释放资源,而不需要主线程调用 join() 来等待它结束。一旦线程被分离,就无法再通过 join() 来等待它,也不能再使用该 std::thread 对象来管理这个线程。

#include <iostream>
#include <thread>
#include <chrono>// 线程函数
void detachedThreadFunction() {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "分离的线程执行完毕。" << std::endl;
}int main() {std::thread t(detachedThreadFunction);std::cout << "主线程不等待分离的线程,继续执行。" << std::endl;t.detach();  // 分离线程std::cout << "主线程继续执行其他任务..." << std::endl;// 主线程可以继续执行其他任务,不需要等待分离的线程return 0;
}

2.3detach陷阱

你考虑一下 上面是不是陷入陷阱?

应该是的 因为

#include <iostream>
#include <thread>
#include <chrono>// 线程函数
void detachedThreadFunction() {std::this_thread::sleep_for(std::chrono::seconds(2));//等待2s才进行std::cout << "分离的线程执行完毕。" << std::endl;
}int main() {std::thread t(detachedThreadFunction);std::cout << "主线程不等待分离的线程,继续执行。" << std::endl;t.detach();  // 分离线程std::cout << "主线程继续执行其他任务..." << std::endl;// 让主线程等待足够长的时间,确保分离的线程执行完毕std::this_thread::sleep_for(std::chrono::seconds(3)); return 0;
}

你会发现主线程已经结束了

2.4 异步执行的特性

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>void threadFunction(int id) {// 模拟线程的工作负载int i=id;if (id%2==0)id=id*3;std::this_thread::sleep_for(std::chrono::seconds(id));std::cout << "Thread " << i << " finished its work." << std::endl;
}int main() {const int numThreads = 5;std::vector<std::thread> threads;// 创建多个线程for (int i = 0; i < numThreads; ++i) {threads.emplace_back(threadFunction, i + 1);}// 等待所有线程完成for (auto& thread : threads) {thread.join();}std::cout << "All threads have finished." << std::endl;return 0;
}
//就会清晰的发现 结果 
Thread 1 finished its work.
Thread 3 finished its work.
Thread 5 finished its work.
Thread 2 finished its work.
Thread 4 finished its work.

windows按工作时间来的,不是按顺序!!!

相关文章:

C++并发以及多线程的秘密

1.基础概念 并发&#xff08;Concurrency&#xff09; 并发是指在同一时间段内&#xff0c;多个任务看起来像是同时执行的。并发并不一定意味着真正的同时执行&#xff0c;它可以是通过时间片轮转等方式在多个任务之间快速切换&#xff0c;让用户感觉多个任务在同时进行。并发…...

自学微信小程序的第十二天

DAY12 1、腾讯地图SDK是一套为开发者提供多种地理位置服务的工具,可以使开发者在自己的应用中加入地图相关功能,轻松访问腾讯地图服务和数据,更好地实现微信小程序的地图功能。 表49:search()方法的常用选项 选项 类型 说明 keyword string POI搜索关键词,默认周边搜索 l…...

⭐算法OJ⭐跳跃游戏【贪心算法】(C++实现)Jump Game 系列 I,II

既股票买卖系列之后的第二组贪心算法题目&#xff1a;跳跃游戏系列。这一篇介绍的两个问题&#xff0c;其输入均为一个数组&#xff0c;每个元素表示在该位置可以跳跃的最大长度。 55. Jump Game You are given an integer array nums. You are initially positioned at the …...

带你从入门到精通——自然语言处理(五. Transformer中的自注意力机制和输入部分)

建议先阅读我之前的博客&#xff0c;掌握一定的自然语言处理前置知识后再阅读本文&#xff0c;链接如下&#xff1a; 带你从入门到精通——自然语言处理&#xff08;一. 文本的基本预处理方法和张量表示&#xff09;-CSDN博客 带你从入门到精通——自然语言处理&#xff08;二…...

ubuntu挂载固态硬盘

Ubuntu 中挂载位于 /dev/sdc1 的固态硬盘&#xff0c;可以按照以下步骤操作&#xff1a; 步骤 1&#xff1a;确认分区信息 首先&#xff0c;确保设备 /dev/sdc1 存在且已正确分区&#xff1a; sudo fdisk -l /dev/sdc # 查看分区表 lsblk # 确认分区路…...

WPF+WebView 基础

1、基于.NET8&#xff0c;通过NuGet添加Microsoft.Web.WebView2。 2、MainWindow.xaml代码如下。 <Window x:Class"Demo.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/win…...

国内光子AI智能引擎:OptoChat AI在南京江北新区亮相

3月3日&#xff0c;从南京市投资促进局传来振奋人心的消息&#xff0c;南京江北新区的一家高科技企业——南京南智先进光电集成技术研究院有限公司&#xff08;简称“南智光电”&#xff09;&#xff0c;携手南京知满科技等合作伙伴&#xff0c;成功研发出国内首个光子AI智能引…...

vscode离线配置远程服务器

目录 一、前提 二、方法 2.1 查看vscode的commit_id 2.2 下载linux服务器安装包 2.3 安装包上传到远程服务器&#xff0c;并进行文件解压缩 三、常见错误 Failed to set up socket for dynamic port forward to remote port&#xff08;vscode报错解决方法&#xff09;-C…...

【安装】SQL Server 2005 安装及安装包

安装包 SQLEXPR.EXE&#xff1a;SQL Server 服务SQLServer2005_SSMSEE.msi&#xff1a;数据库管理工具&#xff0c;可以创建数据库&#xff0c;执行脚本等。SQLServer2005_SSMSEE_x64.msi&#xff1a;同上。这个是 64 位操作系统。 下载地址 https://www.microsoft.com/zh-c…...

使用Maven搭建Spring Boot框架

文章目录 前言1.环境准备2.创建SpringBoot项目3.配置Maven3.1 pom.xml文件3.2 添加其他依赖 4. 编写代码4.1 启动类4.2 控制器4.3 配置文件 5.运行项目6.打包与部署6.1 打包6.2 运行JAR文件 7.总结 前言 Spring Boot 是一个用于快速构建 Spring 应用程序的框架&#xff0c;它简…...

将docker容器打包为.tar包

1. 创建打包脚本 #!/bin/bash # 设置 -e 使得脚本在遇到错误时停止执行 set -e# 必要的参数 exported_container_name"needed_export_container_name_or_id" # 需要被导出的容器的名称或id image_save_name"my_custom_image_name:v25.03.03" # 镜像需…...

SYSTEM文件夹下的文件

sys文件夹下的.c和.h文件里的函数 最重要的倒数第二个 deley文件夹下的.c和.h文件 Systick工作原理 系统滴答定时器是在内核里的 每来一个时钟信号&#xff0c;计数器减一 F1系列时钟源是HCLK&#xff08;就是AHB总线上的时钟信号&#xff09; Systick控制寄存器 Systick重装…...

GPPT: Graph Pre-training and Prompt Tuning to Generalize Graph Neural Networks

GPPT: Graph Pre-training and Prompt Tuning to Generalize Graph Neural Networks KDD22 推荐指数&#xff1a;#paper/⭐⭐#​ 动机 本文探讨了图神经网络&#xff08;GNN&#xff09;在迁移学习中“预训练-微调”框架的局限性及改进方向。现有方法通过预训练&#xff08…...

【SegRNN 源码理解】PMF的多步并行预测

位置编码 elif self.dec_way "pmf":if self.channel_id:# m,d//2 -> 1,m,d//2 -> c,m,d//2# c,d//2 -> c,1,d//2 -> c,m,d//2# c,m,d -> cm,1,d -> bcm, 1, dpos_emb torch.cat([self.pos_emb.unsqueeze(0).repeat(self.enc_in, 1, 1),self.cha…...

构建自己的AI客服【根据用户输入生成EL表达式】

要实现一个基于对话形式的AI客服系统&#xff0c;该系统能够提示用户输入必要的信息&#xff0c;并根据用户的输入生成相应的EL&#xff08;Expression Language&#xff09;表达式编排规则&#xff0c;您可以按照以下步骤进行设计和开发。本文将涵盖系统架构设计、关键技术选型…...

(50)[HGAME 2023 week2]before_main

[HGAME 2023 week2]before_main nss:3501 我们进入那个sub_12EB然后我们发现这个就是base64加密 我们取得qword_4020: 0CxWsOemvJq4zdk2V6QlArj9wnHbt1NfEX/3DhyPoBRLY8pK5FciZau7UMIgTSG 很显然这个是自定义映射base64.然后我们代入我们之前写的base64自定义映射代码 enc:A…...

机器学习数学基础:39.样本和隐含和残差协方差矩阵

假设我们研究学生的数学成绩、英语成绩和学习时间之间的关系。收集了100名学生这三项数据作为样本。 样本协方差矩阵 计算得到的样本协方差矩阵如下&#xff08;假设数据简化&#xff09;&#xff1a; [ V a r ( 数学 ) C o v ( 数学 , 英语 ) C o v ( 数学 , 学习时间 ) C …...

java之http传MultipartFile文件

【需求】前端请求后端做文件上传或者excel上传&#xff0c;后端不解析直接把MultipartFile传给第三方平台&#xff0c;通过http的方式该怎么写 import org.springframework.web.multipart.MultipartFile;import java.io.*; import java.net.HttpURLConnection; import java.ne…...

深入解析SpringMVC中Http响应的实现机制

在Web应用开发中&#xff0c;处理HTTP请求并返回相应的HTTP响应是核心任务之一。SpringMVC作为Java生态中广泛使用的Web框架&#xff0c;提供了灵活且强大的机制来处理HTTP请求和生成HTTP响应。本文将深入探讨SpringMVC中如何实现HTTP响应的返回&#xff0c;涵盖从控制器方法的…...

构建一个支持精度、范围和负数的-Vue-数字输入框

分析并实现一个支持精度、范围和负数控制的数字输入框。 背景 在很多业务中&#xff0c;我们经常需要使用数字输入框&#xff0c;通常这些输入框会涉及到数字校验&#xff0c;比如限制输入范围、设置小数精度、是否允许负数等。每次写表单时&#xff0c;都需要重复定义这些校…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...