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

【c++高级篇】--多任务编程/多线程(Thread)

目录

1.进程和线程的概念:

1.1 进程(Process):

1.2线程(Thread):

1.3 对比总结:

2.多线程编程:

2.1 基于线程的多任务处理(Thread):

2.1.1. mbed.h 中的线程类

2.2 注意事项:(死锁)

2.2.1. 进程死锁

2.2.2 线程死锁

2.2.3 避免死锁(Thread):


1.进程和线程的概念:

进程和线程是操作系统中两个重要的概念,它们之间存在着密切的关系,但有不同的特性和用途。

1.1 进程(Process):

  • 操作系统中资源分配的最小单位,每个进程拥有独立的内存空间、系统资源(文件描述符、网络连接等)和生命周期。进程之间相对独立,无法直接共享彼此的内存空间。

进程虽然无法直接共享彼此内存空间 ,但是操作系统提供了一些机制,使得进程之间可以共享或交换部分资源,但这些共享和通信需要通过特殊的手段实现,而不是像线程那样直接访问共享的内存空间。

 进程间资源共享的常用方式:

  1. 管道(Pipe):允许一个进程将数据写入管道,另一个进程从管道中读取,用于单向通信。

  2. 消息队列(Message Queue):操作系统提供的一种数据结构,用于在多个进程之间发送和接收消息,实现异步通信。

  3. 共享内存(Shared Memory):一种特殊的内存区域,多个进程可以映射到这个区域来进行数据共享。共享内存速度快,但需要借助信号量等同步机制,避免数据竞争。

  4. 信号量(Semaphore):用来控制对共享资源的访问,防止多个进程同时访问导致冲突。

  5. 套接字(Socket):尤其用于分布式系统中,通过网络通信实现跨进程的数据共享和传递。

1.2线程(Thread):

  • 是操作系统中CPU调度的最小单位。线程共享同一进程的内存空间和系统资源,可以认为是进程中的“轻量级”执行单元。同一进程中的线程之间能够共享全局变量和数据,通讯成本低。

1.3 对比总结:


2.多线程编程:

多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。在一般情况下,有两种类型的多任务处理:基于进程和基于线程。

  1. 基于进程的多任务处理:每个进程都有自己的内存空间和系统资源,进程之间相对独立,切换开销较大,但安全性高。每个进程可以运行不同的程序,相互之间的通信通常需要更复杂的机制,比如进程间通信(IPC)。

  2. 基于线程的多任务处理:线程是进程内的一个执行单元,多个线程共享同一进程的内存空间和资源,因此切换开销相对较小,适合需要频繁进行上下文切换的任务。由于共享内存,线程间的通信更为高效,但也带来了同步和安全性的问题。

2.1 基于线程的多任务处理(Thread):

以嵌入式单片为例,在mbed OS中,mbed.h库提供了对线程的支持,使得在嵌入式系统中可以方便地实现多线程。

2.1.1. mbed.h 中的线程类

mbed.h库中,线程主要通过 Thread 类来管理和操作。该类提供了创建、启动、暂停、恢复和终止线程的基本操作方法。

常用的 Thread 类方法有:

  • Thread::start(callback):启动线程,执行指定的回调函数。
  • Thread::join():阻塞当前线程,直到其被调用线程完成。(顺序执行),调用 join() 后,主线程会被阻塞,直到子线程执行完毕。
  • Thread::terminate():强制终止线程的执行。
  • Thread::yield():让出CPU,使其他线程有机会运行。
  • Thread::sleep_for(milliseconds):使线程在指定的毫秒数内休眠。
#include "mbed.h"// 定义LED灯
DigitalOut led1(LED1);
DigitalOut led2(LED2);// 定义线程
Thread thread1;
Thread thread2;// 线程函数1 - 控制LED1闪烁
void led1_thread() {while (true) {led1 = !led1;  // 切换LED1的状态ThisThread::sleep_for(500ms);  // 每500ms切换一次}
}// 线程函数2 - 控制LED2闪烁
void led2_thread() {while (true) {led2 = !led2;  // 切换LED2的状态ThisThread::sleep_for(1000ms);  // 每1000ms切换一次}
}int main() {// 启动线程thread1.start(led1_thread);thread2.start(led2_thread);// 主线程可以执行其他任务,或等待子线程结束thread1.join();thread2.join();
}

2.2 注意事项:(死锁)

进程死锁线程死锁都涉及资源的相互等待,导致无法继续执行。

2.2.1. 进程死锁

进程死锁发生在两个或多个进程之间。当进程A持有资源1并等待资源2,而进程B持有资源2并等待资源1时,两个进程将永远处于等待状态,无法继续执行。

特征

  • 互斥:资源只能被一个进程占用。(不同同时访问)

  • 持有并等待:进程在持有至少一个资源的情况下,申请其他资源。

  • 不剥夺:已经分配给进程的资源在其完成之前不能被强制剥夺。

  • 循环等待:存在一种进程资源的循环等待关系。

示例

进程A持有资源R1,并请求资源R2。 进程B持有资源R2,并请求资源R1。

2.2.2 线程死锁

定义

在多线程程序中,线程死锁通常发生在多个线程尝试以不同的顺序获取多个锁时。例如,线程1持有锁A并等待锁B,而线程2持有锁B并等待锁A,这将导致两个线程永远处于等待状态。

特征

  • 与进程死锁相似,同样具有互斥、持有并等待、不剥夺和循环等待的特征。

  • 线程死锁通常更复杂,因为线程之间的锁依赖关系可能更难以追踪

2.2.3 避免死锁(Thread):

同步和锁

同步指的是在多个线程之间协调它们的执行顺序,以确保某些操作以特定的顺序完成,防止出现竞态条件(race condition)。同步的目的在于确保共享资源的安全访问。

方法:同步可以通过多种方式实现,包括:

  • 互斥锁(Mutex):保证在某一时刻只有一个线程可以访问某个资源。
  • 信号量(Semaphore):控制同时访问某个资源的线程数量。
  • 条件变量(Condition Variable):使线程在某些条件不满足时阻塞,直到条件满足。
  • 读写锁(Read-Write Lock):允许多个线程同时读数据,但在写数据时需要独占访问。

互斥锁(Mutex):

#include "mbed.h"Mutex mutex;  // 创建一个互斥锁
int sharedResource = 0;  // 共享资源void threadTask() {for (int i = 0; i < 5; i++) {mutex.lock();  // 加锁,开始访问共享资源sharedResource++;  // 修改共享资源printf("线程 %d 修改共享资源: %d\n", ThisThread::get_id(), sharedResource);mutex.unlock();  // 解锁,释放共享资源ThisThread::sleep_for(500ms);}
}int main() {Thread thread1;Thread thread2;thread1.start(threadTask);thread2.start(threadTask);thread1.join();thread2.join();printf("最终共享资源值: %d\n", sharedResource);return 0;
}
  • 互斥锁(mutex)确保在同一时刻只有一个线程可以访问和修改sharedResource,避免了数据竞争。
  • 每个线程在修改共享资源前调用mutex.lock(),完成后调用mutex.unlock(),以确保资源安全。

读写锁(Read-Write Lock)

#include "mbed.h"RWLock rwLock;  // 创建读写锁
int sharedData = 0;  // 共享数据// 读线程
void readTask() {for (int i = 0; i < 5; i++) {rwLock.lock_read();  // 获取读锁printf("读线程 %d 读取共享数据: %d\n", ThisThread::get_id(), sharedData);rwLock.unlock_read();  // 释放读锁ThisThread::sleep_for(500ms);}
}// 写线程
void writeTask() {for (int i = 0; i < 3; i++) {rwLock.lock_write();  // 获取写锁sharedData++;  // 更新共享数据printf("写线程 %d 更新共享数据: %d\n", ThisThread::get_id(), sharedData);rwLock.unlock_write();  // 释放写锁ThisThread::sleep_for(1000ms);}
}int main() {Thread readThreads[5];Thread writeThread;// 启动多个读线程for (int i = 0; i < 5; i++) {readThreads[i].start(readTask);}// 启动一个写线程writeThread.start(writeTask);// 等待所有线程完成for (int i = 0; i < 5; i++) {readThreads[i].join();}writeThread.join();printf("所有任务完成\n");return 0;
}
  • 多个读线程readTask)同时读取共享数据sharedData。由于使用了读写锁,多个读线程可以并行地访问共享数据。

  • 写线程writeTask)在更新共享数据时,必须获取写锁,这会阻止其他线程(无论是读线程还是写线程)访问共享数据,直到写操作完成。

相关文章:

【c++高级篇】--多任务编程/多线程(Thread)

目录 1.进程和线程的概念&#xff1a; 1.1 进程&#xff08;Process&#xff09;&#xff1a; 1.2线程&#xff08;Thread&#xff09;&#xff1a; 1.3 对比总结&#xff1a; 2.多线程编程&#xff1a; 2.1 基于线程的多任务处理&#xff08;Thread&#xff09;&#xf…...

【力扣专题栏】两数相加,如何实现存储在链表中的整数相加?

题解目录 1、题目描述解释2、算法原理解析3、代码编写&#xff08;原始版本&#xff09;4、代码编写&#xff08;优化版本&#xff09; 1、题目描述解释 2、算法原理解析 3、代码编写&#xff08;原始版本&#xff09; /*** Definition for singly-linked list.* struct ListN…...

SOLID - 接口隔离原则(Interface Segregation Principle)

SOLID - 接口隔离原则&#xff08;Interface Segregation Principle) 定义 接口隔离原则&#xff08;Interface Segregation Principle&#xff0c;ISP&#xff09;是面向对象设计中的五个基本原则之一&#xff0c;通常缩写为SOLID中的I。这一原则由Robert C. Martin提出&…...

arrylist怎么让他变得不可修改

在Java中&#xff0c;要将一个 ArrayList变得不可修改&#xff0c;你可以使用以下几种方法&#xff1a; ###1. 使用 Collections.unmodifiableList Java 提供了 Collections.unmodifiableList 方法&#xff0c;可以生成一个不可修改的视图。这种方式返回的列表将不允许添加、…...

SpringMVC实战(3):拓展

四、RESTFul风格设计和实战 4.1 RESTFul风格概述 4.1.1 RESTFul风格简介 RESTful&#xff08;Representational State Transfer&#xff09;是一种软件架构风格&#xff0c;用于设计网络应用程序和服务之间的通信。它是一种基于标准 HTTP 方法的简单和轻量级的通信协议&…...

Vue应用中使用xlsx库实现Excel文件导出的完整指南

Vue应用中使用xlsx库实现Excel文件导出的完整指南 在现代Web开发中&#xff0c;经常需要将数据导出为Excel文件&#xff0c;以便于用户进行离线分析或记录。Vue.js作为一个轻量级且高效的前端框架&#xff0c;结合xlsx库可以轻松实现这一功能。本文将详细介绍如何在Vue应用中使…...

【数据分析】Power BI的使用教程

目录 1 Power BI架构1.1 Power BI Desktop1.2 Power BI服务1.3 Power BI移动版 2 Power Query2.1 Power Query编辑器2.2 Power Query的优点2.3 获取数据2.4 数据清洗的常用操作2.4.1 提升标题2.4.2 更改数据类型2.4.3 删除错误/空值2.4.4 删除重复项2.4.5 填充2.4.6 合并列2.4.…...

融合ASPICE与敏捷开发:探索汽车软件开发的最佳实践

ASPICE&#xff08;Automotive SPICE&#xff0c;即汽车软件过程改进和能力dEtermination&#xff09;与敏捷开发在软件开发领域各自具有独特的价值和特点&#xff0c;它们之间的关系可以归纳为既相互区别又相互补充。 一、ASPICE的特点 ASPICE是汽车行业对软件开发流程的一个评…...

后台管理系统的通用权限解决方案(三)SpringBoot整合Knife4j生成接口文档

1 Knife4j介绍 knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案&#xff0c;前身是swagger-bootstrap-ui&#xff0c;取名knife4j是希望它能像一把匕首一样小巧&#xff0c;轻量&#xff0c;并且功能强悍&#xff01; 其底层是对Springfox的封装&#xff0c;使…...

保研考研机试攻略:python笔记(1)

&#x1f428;&#x1f428;&#x1f428;宝子们好呀 ~ 我来更新欠大家的python笔记了&#xff0c;从这一篇开始我们来学下python&#xff0c;当然&#xff0c;如果只是想应对机试并且应试语言以C和C为主&#xff0c;那么大家对python了解一点就好&#xff0c;重点可以看高分篇…...

在浏览器中运行 Puppeteer:解锁新能力

Puppeteer&#xff0c;这个强大的浏览器自动化工具&#xff0c;通常在Node.js环境中运行。但你有没有想过&#xff0c;在浏览器本身中运行Puppeteer会是什么样子&#xff1f;这不仅能让我们利用Puppeteer的功能完成更多任务&#xff0c;还能避开Node.js特定的限制。 支持的功…...

Kafka消费者故障,出现活锁问题如何解决?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka消费者故障&#xff0c;出现活锁问题如何解决&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; Kafka消费者故障&#xff0c;出现活锁问题如何解决&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资…...

pytorch 交叉熵损失函数 BCELoss

BCE Loss 交叉熵损失函数计算公式&#xff1a; BCE Loss - 1/n*(y_actual * log(y_pred) (1 - y_actual) * log(1 - y_pred)) t[i]为标签值&#xff1a;0或者1 o[i]是经过sigmoid后的概率值 BCEWithLogitsLoss 这个损失将Sigmoid层和BCELoss合并在一个类中。 BCEWithLog…...

【进阶】面向对象之接口(多学三招)

文章目录 IDK8开始接口中新增的方法1.允许在接口中定义默认方法,需要使用关键字default修饰2.接口中的默认方法的定义格式3.接口中默认方法的注意事项总结 IDK8开始接口中新增的方法 JDK7以前:接口中只能定义抽象方法。JDK8的新特性:接口中可以定义有方法体的方法。(默认、静态…...

linux上trace code的几种方法

我们在看代码时&#xff0c;总是会遇到下面问题&#xff1a; 1.查看某个场景下的代码执行流 2.查看某个函数被执行时的routine 但是&#xff0c;如果直接查看源码&#xff0c;源码可能代码量大&#xff0c;且分支多&#xff0c;不容易理清。就需要让相关程序运行起来查看。 …...

文件操作(1) —— 文件基础知识

目录 1. 为什么使用文件&#xff1f; 2. 文件种类【按功能分】 3. 文件名 4. 数据文件种类【按存储方式细分】 5. 文件的打开和关闭 5.1 流和标准流 5.2 文件指针 5.3 文件的打开和关闭函数 6. 文件缓冲区 1. 为什么使用文件&#xff1f; 如果没有⽂件&#xff0c;我…...

4K双模显示器7款评测报告

4K双模显示器7款评测报告 HKC G27H7Pro 4K双模显示器 ROG华硕 XG27UCG 4K双模显示器 雷神 ZU27F160L 4K双模显示器 泰坦军团 P275MV PLUS 4K双模显示器 外星人&#xff08;Alienware&#xff09;AW2725QF 4K双模显示器 SANC盛色 D73uPro 4K双模显示器 ANTGAMER蚂蚁电竞 …...

2024.10.24华为(留学生)笔试题解

第一题集装箱堆叠 看注释即可 // 看题目,是最长连续序列的变种。底应该选大的,然后往上堆叠选择次大的(越接近底越好?) // 后续想一下,像是动态规划? // 再一想,好像排序后很容易处理#include <bits/stdc++.h> #include <functional> using namespace st…...

基于neo4j的医疗问诊系统

当你身体不适时&#xff0c;想要找到准确的答案却经常遇到模棱两可的答复&#xff0c;糟心吗&#xff1f;现在&#xff0c;基于neo4j的智能医疗问诊系统为你带来全新体验&#xff01;我们设计了一个具备自动化问答功能的医疗系统&#xff0c;帮助用户快速获取专业的健康知识答案…...

java :String 类

在我们之前的讲解中我们已经了解了很多的Java知识&#xff0c;这节我们讲Java中字符如何定义以及关于String如何使用还有常见的string函数。 【本节目标】 1. 认识 String 类 2. 了解 String 类的基本用法 3. 熟练掌握 String 类的常见操作 4. 认识字符串常量池 5. 认识 …...

关于非中文或者url文本不换行的问题

我在一个写一个简单的url展示的时候&#xff0c;发现url一直溢出不换行&#xff0c;查了各种方法不管用&#xff0c;我请教了我大哥&#xff0c;他直接甩给我两个css放进去就好了 word-break:break-all; 按字符截断换行 /* 支持IE和chrome&#xff0c;FF不支持*/ word-w…...

LeetCode 热题 100之矩阵

1.矩阵置0 思路分析&#xff1a;使用标记数组 记录需要置为 0 的行和列&#xff1a;使用两个布尔数组 zeroRows 和 zeroCols 来记录需要置为 0 的行和列两次遍历 第一遍遍历整个矩阵&#xff0c;找到所有为0的元素&#xff0c;并更新zeroRows和zeroCols&#xff1b;第二遍遍历…...

YOlO系列——yolo v3

文章目录 一、算法原理二、网络结构三、正负样本匹配规则四、损失函数五、边框预测六、性能特点七、应用场景 YOLO-v3&#xff08;You Only Look Once version 3&#xff09;是一种先进的目标检测算法&#xff0c;属于YOLO系列算法的第三代版本。以下是对YOLO-v3的详细介绍&…...

基于Datawhale开源量化投资学习指南(11):LightGBM在量化选股中的优化与实战

1. 概述 在前几篇文章中&#xff0c;我们初步探讨了如何通过LightGBM模型进行量化选股&#xff0c;并进行了一些简单的特征工程和模型训练。在这一篇文章中&#xff0c;我们将进一步深入&#xff0c;通过优化超参数和实现交叉验证来提高模型的效果&#xff0c;并最终通过回测分…...

Python4

4. 更多控制流工具 除了刚介绍的 while 语句&#xff0c;Python 还用了一些别的。我们将在本章中遇到它们。 4.1. if 语句 if elif else if x<0: x 0 print(Negative changed to zero) elif x0: print( zero) else: print(More) 4.2. for 语句 Pyth…...

springboot系列--web相关知识探索六

一、前言 web相关知识探索五中研究了请求中所带的参数是如何映射到接口参数中的&#xff0c;也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、以及自定义对象参数。web相关知识探索五中主要研究自定义对象参数数据绑定底层原理。本次…...

FreeSWITCH 简单图形化界面30 - 使用MYODBC时可能遇到的错误

FreeSWITCH 简单图形化界面30 - 使用MYODBC时可能遇到的错误 测试环境1、 MYODBC 3.51.18 or higher2、分析和解决2.1 解决1&#xff0c;降级MySQL ODBC2.2 解决2&#xff0c;修改FreeSWITCH代码 测试环境 http://myfs.f3322.net:8020/ 用户名&#xff1a;admin&#xff0c;密…...

阿里云物联网的通信方式

阿里云物联网通信的两种方式&#xff0c;一个是物模型&#xff08;分为服务&#xff0c;事件&#xff0c;属性&#xff09;&#xff0c;一个是自定义topic&#xff08;要另外设置数据流转&#xff09; 1.使用产品内的功能定义&#xff0c;&#xff08;其实也就是Topic中定义好的…...

自由职业者的一天:作为小游戏开发者的真实工作日记

大家好&#xff0c;我是小蜗牛。 在这个快节奏的数字时代&#xff0c;自由职业者的生活往往充满了挑战与机遇。作为一名微信小游戏开发者&#xff0c;我的日常工作并不像人们想象中的那样充满光鲜亮丽的画面&#xff0c;而是由无数的编码、调试和创意碰撞组成的。今天&#xf…...

【RL Latest Tech】分层强化学习:Option-Critic架构算法

&#x1f4e2;本篇文章是博主强化学习RL领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在&#x1f…...