音视频学习笔记——c++多线程(一)
✊✊✊🌈大家好!本篇文章主要整理了部分多线程相关的内容重点😇。首先讲解了多进程和多线程并发的区别以及各自优缺点,之后讲解了Thead线程库的基本使用。
本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习,梳理总结后写下文章,对音视频相关内容感兴趣的读者,可以点击观看课程网址:零声教育
🎡导航小助手🎡
- 一、多进程与多线程
- 二、Thead线程库的基本使用
- 三、小结
一、多进程与多线程
首先有一个直观的理解:
1.进程就是运行中的程序
2.线程就是进程中的进程
操作系统中可以有多个进程,一个进程中也可以有多个线程。
1.1 多线程并发
多进程并发是将一个应用程序划分为多个独立的进程(每个进程只有一个线程),这些独立的进程之间相互可以通信,共同完成任务。操作系统常常对进程提供大量的保护机制,避免出现一个进程修改其他进程的数据,因此,相对于多线程,使用多进程更容易写出相对安全的代码。但这也造成了多进程并发存在两个不足之处:
- 进程间的通信,无论是使用信号、套接字、还是文件、管道等方式,其使用要么比较复杂,要么就是速度较慢或者两者兼而有之。
- 运行多个线程,需要操作系统花费很多资源进行管理。
在多个进程并发完成一个任务时,常会出现操作同一个数据以及进程之间的相互通信,因此,多进程并发不是一个很好的选择。
1.2 多线程并发
多线程并发:同一个进程中执行多个线程。
- 优点:线程是轻量级的进程,每个线程可以独立的运行不同的指令序列,且线程不独立拥有资源,依赖于创建它的进程而存在。
同一进程中的多个线程能够很方便的进行数据共享以及通信,比进程更适用于并发操作。
不足:缺少操作系统提供的保护机制。在多线程共享数据及通信时,需程序员做更多的操作,并且还需极力避免死锁。
二、Thead线程库的基本使用
2.1 创建线程
要创建线程,我们需要一个可调用的函数或函数对象,作为线程的入口点。
在C++11中,我们可以使用函数指针、函数对象或lambda表达式来实现。
创建线程的基本语法如下:
#include <thread>std::thread t(function_name, args...);
function_name是线程入口点的函数或可调用对象args...是传递给函数的参数
创建线程后,我们可以使用t.join()等待线程完成,或者使用t.detach()分离线程,让它在后台运行。
实例1:
#include <iostream>#include <thread>using namespace std;void doit() { cout << "World!" << endl; }int main() {thread a([] {cout << "Hello, " << flush;}), b(doit);a.join();b.join();return 0;}
运行结果:


上面两次结果并不相同,这是因为多线程运行时是以异步方式执行的,与我们平时写的同步方式不同。异步方式可以同时执行多条语句,谁先执行得快,谁先执行完。
实例2:
#include <iostream>#include <thread>using namespace std;void thread_1(){cout<<"线程t"<<endl;}void print_message(const string& message) { cout << message <<endl;cout << "线程 t" << endl;}void increment(int& x) { ++x;cout << "线程 t2" << endl;}int main() { cout << "主线程1\n";thread t(thread_1);// 开启线程t,调用:thread_1()t.join();cout << "子线程t结束\n";string message = "Hello, world!"; thread t1(print_message, message);// 开启线程t1,调用:print_message()t1.join(); int x = 0; thread t2(increment, ref(x));//开启线程t1,调用:increment() t2.join(); cout << "子线程t2结束\n";cout << x << endl; cout << "全部子进程结束\n";return 0;}
运行结果:

从上面结果,我们很明显能看出,使用t.join()后程序需要等待进程t结束后,才会接着进行。
注意:thread在传递参数时,是以右值传递的。
我们在传递引用的时候,需要用到std::ref和std::cref
std::ref可以包装按引用传递的值。std::cref可以包装按const引用传递的值。
2.2 join与detach方式
当线程启动后,一定要在和线程相关联的thread销毁前,确定以何种方式等待线程执行结束。比如上
例中的join。
• detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不等待新线程结束。
• join方式,等待启动的线程完成,才会继续往下执行。
可以使用joinable判断是join模式还是detach模式。
示例1:join举例
#include <iostream>#include <thread>using namespace std;void thread_1() {while (1) {cout<<"子线程1"<<endl;}}void thread_2(int x) {while (1) {cout<<"子线程2"<<endl;}}int main() {thread first(thread_1);// 开启线程,调用:thread_1()thread second(thread_2, 100);// 开启线程,调用:thread_2(100)first.join(); // pauses until first finishes 这个操作完了之后才能destroyedsecond.join(); // pauses until second finishes//join完了之后,才能往下执行。while (1) {std::cout << "主线程\n";}return 0;}

线程1和线程2写的是死循环,那么在两个子线程没结束前,主线程不会执行。
示例2:detach举例
#include <iostream>#include <thread>using namespace std;void thread_1() {while (1) {cout<<"子线程1"<<endl;}}void thread_2(int x) {while (1) {cout<<"子线程2"<<endl;}}int main() {thread first(thread_1);// 开启线程,调用:thread_1()thread second(thread_2, 100);// 开启线程,调用:thread_2(100)first.join(); // pauses until first finishes 这个操作完了之后才能destroyedsecond.join(); // pauses until second finishes//join完了之后,才能往下执行。while (1) {std::cout << "主线程\n";}return 0;}
运行结果:

可以看出,主线程不会等待子线程1和2结束。如果主线程运行结束,程序则结束。
2.3 joinable
joinable()返回一个bool值,判断是join模式还是detach模式。
使用方法;
if (myThread.joinable()) 1 foo.join();
三、小结
- 多进程安全但是浪费操作系统资源且进程间相互通信比较麻烦。多线程则可以很好的处理这两个问题,但是使用时需要使用更多操作确保安全。
- C++11提供了语言层面上的多线程,包含在头文件中。它解决了跨平台的问题,提供了管理线程、保护共享数据、线程间同步操作、原子操作等类。主要讲解了Thead线程库的基本使用,包括join()、joinable()和detach(),并举了很多例子进行补充。
感谢大家阅读!
接下来还会继续更新多线程相关知识,感兴趣的可以看其他笔记!
相关文章:
音视频学习笔记——c++多线程(一)
✊✊✊🌈大家好!本篇文章主要整理了部分多线程相关的内容重点😇。首先讲解了多进程和多线程并发的区别以及各自优缺点,之后讲解了Thead线程库的基本使用。 本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统…...
消息队列常见问题
总的来讲,消息队列常见问题要么消息不能多,要么不能少,还有顺序性,以及积压处理的问题等。 1.消息不能多 也就是说,消息不能重复消费,随之带来的幂等性问题。 解决:一般结合业务场景…...
【leetcode热题】二叉树的前序遍历
难度: 中等通过率: 49.5%题目链接:. - 力扣(LeetCode) 题目描述 给定一个二叉树,返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 1\2/3 输出: [1,2,3]进阶: 递归算法很简单,你可以通过迭代…...
Linux命令记不住?保姆级教程来了
在软件开发过程中,Linux操作系统因其稳定性、安全性和高效性而备受青睐。作为开发者,熟练掌握Linux常用命令,不仅可以提高工作效率,还能更好地管理服务器和进行代码部署。本文将介绍一些开发常用的Linux命令及其应用场景ÿ…...
基于GitBucket的Hook构建ES检索PDF等文档全栈方案
背景 之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo,预期建设方案是使用触发器类型从公共的文档源拉取最新的文件,然后调用Java将文件转Base64后入ES建索引,再提供封装接口给前端做查询之用。 由于全部内容过长ÿ…...
C语言:数组、字符串知识点整理:
数组:(长度的计算) 补充:数组长度sizeof(arr)/sizeof(arr[0]) 注意:!!!不适用于当arr 充当形参时(函数传参)!!! 因为函数…...
Linux mmap系统调用
文章目录 前言一、mmap()函数简介二、代码演示2.1 mmap使用场景2.2 私有匿名映射2.3 私有文件映射2.4 共享匿名映射2.5 共享文件映射 参考 前言 NAMEmmap, munmap - map or unmap files or devices into memorySYNOPSIS#include <sys/mman.h>void *mmap(void *addr, siz…...
VSCode搭建ARM开发环境
为了构建Cortex M系列单片机免费开源的开发环境,网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式,下面记录环境搭建的流程。 我这边的PC环境为 WIN7专业版64bit。 需要用到的工具 Visual Studio CodeSTM32CubemxARM GCC 交叉编译工具链&#x…...
centos7 python3.12.1 报错 No module named _ssl
https://blog.csdn.net/Amio_/article/details/126716818 安装python cd /usr/local/src wget https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz tar -zxvf Python-3.12.1.tgz cd Python-3.12.1/ ./configure -C --enable-shared --with-openssl/usr/local/opens…...
探索HTTP协议:网络通信的基石
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
几大开源免费的 JavaScript 富文本编辑器测评
MarkDown 编辑器用的时间长了,发现发现富文本编辑器用起来是真的舒服。 一直以来写博客都是用的 MarkDown 编辑器,MarkDown 文档简单方便,使用几个简单的符号就可以定义出样式统一的富文本内容。写博客的时间长了,小玖就越来越排…...
MongoDB聚合运算符:$dateFromString
文章目录 语法使用使用例子对规则进行说明格式指示符 举例日期转换错误处理onError空值的粗粒 onNull $dateFromString聚合运算符将日期时间字符串转换为日期对象。 语法 { $dateFromString: {dateString: <dateStringExpression>,format: <formatStringExpression&g…...
Postman(注册,使用,作用)【详解】
目录 一、Postman 1. Postman介绍 2. 安装Postman 3. 注册帐号再使用(可保存测试记录) 4. 创建workspace 5. 测试并保存测试记录 一、Postman postman工具可以发送不同方式的请求,浏览器只能发送get请求(所有用这个工具) 在前后端分离开发模式下,前端技术人员…...
电商数据分析18——电商广告投放的数据分析与优化
目录 写在开头1. 电商广告投放的挑战与机遇1.1 广告投放的主要目标与挑战1.2 广告数据分析的价值 2. 数据分析在广告投放中的应用2.1 目标受众分析与精准定位2.2 广告效果评估与ROI分析2.3 A/B测试与广告内容优化 3. 广告投放优化的实践案例3.1 案例分享:精准定向提…...
Docker下Jenkins打包java项目并部署
docker 构建Jenkins sudo docker run --namezen_haslett --userjenkins --privilegedtrue --volume/home/cyf/server/jenkins/jenkins_home:/var/jenkins_home -v /usr/lib/jvm/java-17-openjdk-amd64:/usr/lib/jvm/java-17-openjdk-amd64 -v /usr/lib/maven/apache-mav…...
android 快速实现 recyclerview 的所有item 都执行动画
1.在adapter 里面重写onViewAttachedToWindow 和 onViewDetachedFromWindow 两个方法 package com.example.widget;import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animat…...
Excel转pdf
1、excel-内存值--Workbook 转pdf /** * excel To pdf * * param outPath 输出路径 * param workbook excel-内存值 * throws IOException */ public static void excelToPdf(String outPath,Workbook workbook) throws IOException, DocumentException { Document documentnul…...
QT:用opencv的KNN识别图片中的LED数字(一)
前言 一款功能测试的软件demo,使用了QT作为界面,主要使用了opencv的KNN识别,使用gstreamer作为管道,用来打开图片。后期会写一篇打开摄像头实时识别的文章。 (正在写,未完成,稍候) 效果一预览: 效果二预览: 效果三预览: 正在写。。。 设计思路 1. 软件UI设计 2. …...
leetcode72. 编辑距离
leetcode72. 编辑距离 题目 思路 dp[i][j] 代表 word1 到 i 位置转换成 word2 到 j 位置需要最少步数,所以, 当 word1[i] word2[j],dp[i][j] dp[i-1][j-1]; 当 word1[i] ! word2[j],dp[i][j] 1 min(dp[i-1][j-1]…...
R语言的数据类型与数据结构:向量、列表、矩阵、数据框及操作方法
R语言的数据类型与数据结构:向量、列表、矩阵、数据框及操作方法 介绍向量列表矩阵数据框 介绍 R语言拥有丰富的数据类型和数据结构,以满足各类数据处理和分析的需求。本文将分享R语言中的数据类型,包括向量、列表、矩阵、数据框等ÿ…...
VCS仿真器下UVM调试实战:手把手解决uvm_hdl_force权限与$urandom_range范围溢出
VCS仿真器下UVM调试实战:手把手解决uvm_hdl_force权限与$urandom_range范围溢出 在芯片验证领域,UVM(Universal Verification Methodology)已成为事实上的标准。然而,当我们在Synopsys VCS这样的商业仿真器上实现UVM验…...
终极指南:如何用KMS_VL_ALL_AIO一键永久激活Windows和Office系统
终极指南:如何用KMS_VL_ALL_AIO一键永久激活Windows和Office系统 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为Windows系统频繁弹出激活提示而烦恼吗?Office文档…...
别再靠意志力了!我用Cold Turkey Blocker Pro的这5个高级功能,彻底告别上班摸鱼
用Cold Turkey Blocker Pro构建无痛专注系统:5个被低估的高级功能实践指南 你是否经历过这样的场景:明明手头有重要项目要完成,却不知不觉刷了两小时社交媒体?或是计划用番茄钟高效工作,结果刚过10分钟就忍不住点开了新…...
工控机常见故障及排除方法有哪些(工控机常见的故障维修方法有哪些
大家好,我是阿强,在工控厂商行业摸爬滚打了 17 年,从开始的学徒到现在负责技术支持,见过太多工业现场的 "惊魂时刻"。很多时候,一条生产线因为一台工控主机突然故障停摆,每分钟都在产生真金白银的…...
RyzenAdj:AMD Ryzen 处理器电源管理的终极调优指南
RyzenAdj:AMD Ryzen 处理器电源管理的终极调优指南 【免费下载链接】RyzenAdj Adjust power management settings for Ryzen APUs 项目地址: https://gitcode.com/gh_mirrors/ry/RyzenAdj RyzenAdj 是一款专为 AMD Ryzen 移动处理器设计的开源电源管理工具&a…...
Android音频压缩实战:对比Concentus与libopus,谁才是你的项目最优选?
Android音频压缩实战:Concentus与libopus深度评测与选型指南 在移动应用开发中,音频处理一直是性能敏感型任务。当我们需要在Android平台上实现高质量的音频压缩时,OPUS编码器无疑是当前最先进的选择之一。但面对纯Java实现的Concentus和需要…...
OpenClaw与系统环境冲突:Windows/Mac系统兼容问题解决指南
OpenClaw 与系统环境冲突:Windows/Mac 系统兼容问题解决指南引言在当今多平台协作的时代,软件能否在不同操作系统上顺畅运行变得至关重要。OpenClaw,作为一款功能强大的专业工具(例如:数据处理、设计、开发环境等&…...
Effective harnesses for long-running agents翻译
⚠️ 在开始阅读之前,如果你对 实时 Agent / 数字人 / 多模态系统 / LiveKit 架构 感兴趣, 欢迎先到 GitHub 给项目点一个 ⭐ Star,这是对开源作者最大的支持。🚀 AlphaAvatar 项目地址(强烈建议先收藏,该项…...
OneNote到Markdown终极转换指南:5步轻松迁移你的珍贵笔记
OneNote到Markdown终极转换指南:5步轻松迁移你的珍贵笔记 【免费下载链接】onenote-md-exporter ConsoleApp to export OneNote notebooks to Markdown formats 项目地址: https://gitcode.com/gh_mirrors/on/onenote-md-exporter OneNote Md Exporter是一款…...
定时任务调度
定时任务调度:自动化管理的智慧引擎 在现代信息化系统中,定时任务调度是确保业务高效运行的核心技术之一。无论是每天凌晨的数据备份,还是每周的报表生成,亦或是电商平台的秒杀活动预热,都离不开定时任务的精准调度。…...
