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

音视频学习笔记——c++多线程(一)

✊✊✊🌈大家好!本篇文章主要整理了部分多线程相关的内容重点😇。首先讲解了多进程和多线程并发的区别以及各自优缺点,之后讲解了Thead线程库的基本使用。


本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统学习,梳理总结后写下文章,对音视频相关内容感兴趣的读者,可以点击观看课程网址:零声教育


🎡导航小助手🎡

    • 一、多进程与多线程
    • 二、Thead线程库的基本使用
    • 三、小结

一、多进程与多线程

首先有一个直观的理解:
  1.进程就是运行中的程序
  2.线程就是进程中的进程

操作系统中可以有多个进程,一个进程中也可以有多个线程。

1.1 多线程并发
多进程并发是将一个应用程序划分为多个独立的进程(每个进程只有一个线程),这些独立的进程之间相互可以通信,共同完成任务。操作系统常常对进程提供大量的保护机制避免出现一个进程修改其他进程的数据,因此,相对于多线程,使用多进程更容易写出相对安全的代码。但这也造成了多进程并发存在两个不足之处

  1. 进程间的通信,无论是使用信号、套接字、还是文件、管道等方式,其使用要么比较复杂,要么就是速度较慢或者两者兼而有之。
  2. 运行多个线程,需要操作系统花费很多资源进行管理。

在多个进程并发完成一个任务时,常会出现操作同一个数据以及进程之间的相互通信,因此,多进程并发不是一个很好的选择。
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();

三、小结

  1. 多进程安全但是浪费操作系统资源且进程间相互通信比较麻烦。多线程则可以很好的处理这两个问题,但是使用时需要使用更多操作确保安全。
  2. C++11提供了语言层面上的多线程,包含在头文件中。它解决了跨平台的问题,提供了管理线程、保护共享数据、线程间同步操作、原子操作等类。主要讲解了Thead线程库的基本使用,包括join()、joinable()和detach(),并举了很多例子进行补充。

感谢大家阅读!
接下来还会继续更新多线程相关知识,感兴趣的可以看其他笔记!

相关文章:

音视频学习笔记——c++多线程(一)

✊✊✊&#x1f308;大家好&#xff01;本篇文章主要整理了部分多线程相关的内容重点&#x1f607;。首先讲解了多进程和多线程并发的区别以及各自优缺点&#xff0c;之后讲解了Thead线程库的基本使用。 本专栏知识点是通过<零声教育>的音视频流媒体高级开发课程进行系统…...

消息队列常见问题

总的来讲&#xff0c;消息队列常见问题要么消息不能多&#xff0c;要么不能少&#xff0c;还有顺序性&#xff0c;以及积压处理的问题等。 1.消息不能多 也就是说&#xff0c;消息不能重复消费&#xff0c;随之带来的幂等性问题。 解决&#xff1a;一般结合业务场景&#xf…...

【leetcode热题】二叉树的前序遍历

难度&#xff1a; 中等通过率&#xff1a; 49.5%题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个二叉树&#xff0c;返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 1\2/3 输出: [1,2,3]进阶: 递归算法很简单&#xff0c;你可以通过迭代…...

Linux命令记不住?保姆级教程来了

在软件开发过程中&#xff0c;Linux操作系统因其稳定性、安全性和高效性而备受青睐。作为开发者&#xff0c;熟练掌握Linux常用命令&#xff0c;不仅可以提高工作效率&#xff0c;还能更好地管理服务器和进行代码部署。本文将介绍一些开发常用的Linux命令及其应用场景&#xff…...

基于GitBucket的Hook构建ES检索PDF等文档全栈方案

背景 之前已简单使用ES及Kibana和在线转Base64工具实现了检索文档的demo&#xff0c;预期建设方案是使用触发器类型从公共的文档源拉取最新的文件&#xff0c;然后调用Java将文件转Base64后入ES建索引&#xff0c;再提供封装接口给前端做查询之用。 由于全部内容过长&#xff…...

C语言:数组、字符串知识点整理:

数组&#xff1a;&#xff08;长度的计算&#xff09; 补充&#xff1a;数组长度sizeof(arr)/sizeof(arr[0]) 注意&#xff1a;&#xff01;&#xff01;&#xff01;不适用于当arr 充当形参时&#xff08;函数传参&#xff09;&#xff01;&#xff01;&#xff01; 因为函数…...

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系列单片机免费开源的开发环境&#xff0c;网络上了解来看VSCODEGCCJLINK是一套比较高效的组合方式&#xff0c;下面记录环境搭建的流程。 我这边的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协议:网络通信的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

几大开源免费的 JavaScript 富文本编辑器测评

MarkDown 编辑器用的时间长了&#xff0c;发现发现富文本编辑器用起来是真的舒服。 一直以来写博客都是用的 MarkDown 编辑器&#xff0c;MarkDown 文档简单方便&#xff0c;使用几个简单的符号就可以定义出样式统一的富文本内容。写博客的时间长了&#xff0c;小玖就越来越排…...

MongoDB聚合运算符:$dateFromString

文章目录 语法使用使用例子对规则进行说明格式指示符 举例日期转换错误处理onError空值的粗粒 onNull $dateFromString聚合运算符将日期时间字符串转换为日期对象。 语法 { $dateFromString: {dateString: <dateStringExpression>,format: <formatStringExpression&g…...

Postman(注册,使用,作用)【详解】

目录 一、Postman 1. Postman介绍 2. 安装Postman 3. 注册帐号再使用(可保存测试记录) 4. 创建workspace 5. 测试并保存测试记录 一、Postman postman工具可以发送不同方式的请求,浏览器只能发送get请求(所有用这个工具) 在前后端分离开发模式下&#xff0c;前端技术人员…...

电商数据分析18——电商广告投放的数据分析与优化

目录 写在开头1. 电商广告投放的挑战与机遇1.1 广告投放的主要目标与挑战1.2 广告数据分析的价值 2. 数据分析在广告投放中的应用2.1 目标受众分析与精准定位2.2 广告效果评估与ROI分析2.3 A/B测试与广告内容优化 3. 广告投放优化的实践案例3.1 案例分享&#xff1a;精准定向提…...

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 位置需要最少步数&#xff0c;所以&#xff0c; 当 word1[i] word2[j]&#xff0c;dp[i][j] dp[i-1][j-1]&#xff1b; 当 word1[i] ! word2[j]&#xff0c;dp[i][j] 1 min(dp[i-1][j-1]…...

R语言的数据类型与数据结构:向量、列表、矩阵、数据框及操作方法

R语言的数据类型与数据结构&#xff1a;向量、列表、矩阵、数据框及操作方法 介绍向量列表矩阵数据框 介绍 R语言拥有丰富的数据类型和数据结构&#xff0c;以满足各类数据处理和分析的需求。本文将分享R语言中的数据类型&#xff0c;包括向量、列表、矩阵、数据框等&#xff…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...