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

鸿蒙南向开发教程 Day 3 附录:线程与进程详解

目标:理解线程与进程的本质区别、状态模型、调度机制,以及在 OpenHarmony 轻量系统中的实现


一、进程(Process)是什么?

1.1 核心定义

进程是操作系统进行资源分配和调度的基本单位,是程序的一次执行实例。

┌─────────────────────────────────────────┐ │ 进程(Process) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 代码段 │ │ 数据段 │ │ 堆栈段 │ │ │ │ (Text) │ │ (Data) │ │ (Stack) │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 打开文件 │ │ 信号处理 │ │ 地址空间 │ │ │ │ 列表 │ │ 程序 │ │ (虚拟内存)│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ 资源所有权:内存、文件、设备、句柄等 │ └─────────────────────────────────────────┘

1.2 进程的组成

组成部分说明特点
代码段(Text)程序指令的二进制代码只读,可被多个进程共享
数据段(Data)全局变量、静态变量可读写
堆(Heap)动态分配的内存(malloc)向上增长,需手动管理
栈(Stack)局部变量、函数参数、返回地址向下增长,自动管理
进程控制块(PCB)操作系统管理进程的数据结构包含 PID、状态、优先级等

1.3 进程的状态模型

┌─────────┐ │ 创建 │ ← fork() / 系统初始化 │ (New) │ └────┬────┘ ↓ ┌─────────┐ 调度器选择 ┌─────────┐ ┌──→ │ 就绪 │ ────────────────→ │ 运行 │ │ │(Ready) │ │(Running)│ │ └─────────┘ ←──────────────── └────┬───┘ │ ↑ 时间片用完/被抢占 │ │ │ ↓ I/O 请求 / 等待事件 │ ┌────┴────┐ ┌─────────┐ └────┤ 阻塞 │ ← I/O完成/事件到达 │ 阻塞 │ │(Blocked)│ │(Blocked)│ └─────────┘ └─────────┘ ↓ ┌─────────┐ │ 终止 │ ← exit() / 被杀死 │(Terminated) └─────────┘

三态模型:就绪(Ready)→ 运行(Running)→ 阻塞(Blocked)


二、线程(Thread)是什么?

2.1 核心定义

线程是 CPU 调度的基本单位,是进程内的执行流。一个进程可以包含多个线程,它们共享进程的资源,但拥有独立的执行上下文。

┌─────────────────────────────────────────┐ │ 进程(Process) │ │ 共享资源:代码、数据、堆、文件等 │ │ ┌─────────────────────────────────────┐ │ │ │ 线程1 │ 线程2 │ 线程3 │ ... │ │ │ │ ┌────┐ │ ┌────┐ │ ┌────┐ │ │ │ │ │ │寄存器│ │ │寄存器│ │ │寄存器│ │ │ │ │ │ │程序计数器│ │ │程序计数器│ │ │程序计数器│ │ │ │ │ │ │栈指针 │ │ │栈指针 │ │ │栈指针 │ │ │ │ │ │ │状态字 │ │ │状态字 │ │ │状态字 │ │ │ │ │ │ └──┬─┘ │ └──┬─┘ │ └──┬─┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 独立栈 │ 独立栈 │ 独立栈 │ │ │ │ └─────────────────────────────────────┘ │ │ 线程私有:寄存器、程序计数器、栈 │ └─────────────────────────────────────────┘

2.2 线程的组成

组成部分说明是否共享
线程 ID(TID)线程唯一标识私有
程序计数器(PC)下一条指令地址私有
寄存器组通用寄存器、状态寄存器私有
栈(Stack)局部变量、函数调用链私有
线程局部存储(TLS)线程私有全局变量私有
代码段程序指令✅ 进程内共享
数据段/堆全局变量、动态内存✅ 进程内共享
打开文件文件描述符表✅ 进程内共享

2.3 线程的状态

线程状态与进程类似,但更轻量:

┌─────────┐ 创建 ┌─────────┐ 调度 ┌─────────┐ │ 新建 │ ──────→ │ 就绪 │ ──────→ │ 运行 │ │ (New) │ │(Ready) │ │(Running)│ └─────────┘ └────┬────┘ └───┬────┘ ↑ │ │ 阻塞事件 ↓ ┌────┴────┐ ┌─────────┐ │ 阻塞 │ ←───── │ 阻塞 │ │(Blocked)│ 事件到达 │(Blocked)│ └─────────┘ └─────────┘ ↓ ┌─────────┐ │ 终止 │ │(Dead) │ └─────────┘

三、进程 vs 线程:核心对比

对比维度进程(Process)线程(Thread)
定义资源分配的基本单位CPU 调度的基本单位
内存空间独立的地址空间共享进程的地址空间
切换开销大(需切换页表、刷新 TLB)小(只需切换寄存器和栈)
通信方式IPC(管道、消息队列、共享内存、套接字)直接读写共享变量(需同步机制)
创建开销大(复制地址空间)小(共享大部分资源)
崩溃影响不影响其他进程可能导致整个进程崩溃
并发性低(重量级)高(轻量级)
系统限制数量受内存限制数量受栈空间限制

3.1 形象比喻

比喻进程线程
工厂模型一家独立的工厂(有独立场地、设备、工人)工厂内的生产线(共享场地设备,独立执行任务)
厨房模型独立的厨房(有独立食材、厨具、厨师)厨房内的厨师(共享食材厨具,各自做菜)
程序模型打开的两个 Word 文档(独立编辑)一个 Word 内的拼写检查和自动保存(同时运行)

四、OpenHarmony 轻量系统中的线程

4.1 系统架构

OpenHarmony 轻量系统(LiteOS-M)是单进程多线程架构:

┌─────────────────────────────────────────┐ │ OpenHarmony 轻量系统 │ │ (单进程,多线程) │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 内核空间 │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │ 线程调度 │ │ 内存管理 │ │ │ │ │ │ (Tick) │ │ (Heap) │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 用户空间 │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │主线程│ │任务A│ │任务B│ │中断 │ │ │ │ │ │Init │ │Thread│ │Thread│ │Handler│ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ │ │ │ │ │ 共享:全局变量、代码段、堆内存 │ │ │ │ 私有:栈空间(每个线程独立) │ │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────┘

关键特点

  • 没有独立的"进程"概念,整个系统运行在一个地址空间
  • 所有线程共享全局内存
  • 线程切换只需保存/恢复寄存器和栈指针

4.2 线程在 Hi3861 中的实现

Hi3861 使用LiteOS-M 内核,线程即 LiteOS 的任务(Task)

┌─────────────────────────────────────────┐ │ LiteOS-M 任务管理 │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 就绪队列(按优先级排序) │ │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ │ │Prio0│→│Prio1│→│Prio2│→│Prio3│→...│ │ │ │ │High │ │ │ │ │ │Low │ │ │ │ │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ │ └─────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 任务控制块(TCB) │ │ │ │ ┌─────────┐ ┌─────────┐ │ │ │ │ │任务ID │ │栈指针 │ │ │ │ │ │优先级 │ │程序计数器│ │ │ │ │ │状态 │ │寄存器保存│ │ │ │ │ │栈大小 │ │任务入口 │ │ │ │ │ └─────────┘ └─────────┘ │ │ │ └─────────────────────────────────────┘ │ └─────────────────────────────────────────┘

4.3 CMSIS-RTOS2 线程 vs LiteOS-M 任务

CMSIS-RTOS2 概念LiteOS-M 实现说明
osThreadLOS_Task线程 = 任务
osThreadNew()LOS_TaskCreate()创建任务
osThreadSuspend()LOS_TaskSuspend()挂起任务
osThreadResume()LOS_TaskResume()恢复任务
osThreadTerminate()LOS_TaskDelete()删除任务
osPriorityNormal优先级数值数值越小优先级越高

五、线程调度机制

5.1 抢占式调度

LiteOS-M 使用优先级抢占 + 时间片轮转调度:

时间轴 → Tick 0: [Task A: Prio 3] ← 运行 [Task B: Prio 5] 就绪 [Task C: Prio 7] 就绪 Tick 10: [Task B 就绪,Prio 5 > Task A 的 3?否] → Task A 继续 Tick 20: [Task D 就绪,Prio 2] → 抢占! [Task D: Prio 2] ← 运行(抢占) [Task A: Prio 3] 就绪(被抢占) [Task B: Prio 5] 就绪 [Task C: Prio 7] 就绪 Tick 30: [Task D 阻塞/I/O] → 调度最高就绪 [Task A: Prio 3] ← 运行(恢复)

规则

  1. 高优先级任务就绪 → 立即抢占低优先级任务
  2. 同优先级任务 → 时间片轮转(默认 10ms)
  3. 任务阻塞(等待 I/O、延时)→ 让出 CPU

5.2 线程状态转换

┌─────────┐ │ 创建 │ osThreadNew() │ (New) │ └────┬────┘ ↓ ┌─────────┐ 调度器选择 ┌─────────┐ ┌──→ │ 就绪 │ ────────────────→ │ 运行 │ │ │(Ready) │ │(Running)│ │ └────┬────┘ ←──────────────── └────┬────┘ │ ↑ 时间片用完/被抢占 │ │ │ ↓ osDelay / osMutexAcquire │ ┌────┴────┐ ┌─────────┐ └────┤ 阻塞 │ ← 延时到期/锁释放 │ 阻塞 │ │(Blocked)│ │(Blocked)│ │ │ │ │ │ osDelay │ │ osMutex │ │ 到期 │ │ 释放 │ └─────────┘ └─────────┘ ↓ ┌─────────┐ │ 终止 │ osThreadTerminate() │(Dead) │ └─────────┘

六、线程栈(Stack)详解

6.1 栈的作用

栈是线程私有的内存区域,用于:

用途说明
局部变量函数内定义的变量
函数参数传递给子函数的参数
返回地址函数调用后返回到哪里
寄存器保存上下文切换时保存寄存器值
中断现场中断发生时保存 CPU 状态

6.2 栈溢出危害

栈空间(假设 1024 字节): ┌─────────────────────────────────────────┐ ← 栈底(高地址) │ 已使用区域 │ │ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │main │ │funcA│ │funcB│ │funcC│ ... │ │ │局部 │ │局部 │ │局部 │ │大数组│ │ │ │变量 │ │变量 │ │变量 │ │[1024]│ │ ← 栈溢出!超过 1024 字节 │ └─────┘ └─────┘ └─────┘ └─────┘ │ │ ↑ │ │ 栈指针 SP │ ├─────────────────────────────────────────┤ │ 未使用区域 │ │ ... │ └─────────────────────────────────────────┘ ← 栈顶(低地址) 溢出后果: 1. 覆盖其他线程的栈 → 数据损坏 2. 覆盖全局变量 → 程序逻辑错误 3. 覆盖代码段 → 程序崩溃(HardFault)

Hi3861 栈大小建议

线程类型建议栈大小说明
简单任务512 ~ 1024 字节少量局部变量,无深层调用
一般任务1024 ~ 2048 字节正常函数调用,中等局部变量
复杂任务2048 ~ 4096 字节深层递归、大数组、网络协议栈
中断处理与线程共享中断使用当前线程的栈

七、线程安全与临界区

7.1 什么是线程安全?

线程安全:多个线程同时访问共享资源时,程序行为正确,数据一致。

线程不安全示例(无保护): Thread A: 读取 g_count = 5 → 计算 5+1 = 6 → [被抢占] Thread B: 读取 g_count = 5 → 计算 5+1 = 6 → 写入 g_count = 6 Thread A: [恢复] 写入 g_count = 6 结果:g_count = 6,但期望 = 7(两次++) 一次更新丢失!

7.2 临界区保护方法

方法适用场景特点
关闭中断单核、极短临界区最简单,但影响实时性
互斥锁(Mutex)长临界区、可阻塞支持递归、优先级继承
自旋锁(Spinlock)多核、短临界区忙等待,不阻塞
原子操作简单变量读写硬件指令保证,无锁

Hi3861 是单核 Cortex-M0+,常用方法

// 方法1:关中断(最轻量)uint32_tintSave=LOS_IntLock();// 保存并关闭中断// ... 临界区 ...LOS_IntRestore(intSave);// 恢复中断// 方法2:互斥锁(推荐,支持阻塞等待)osMutexAcquire(mid,osWaitForever);// ... 临界区 ...osMutexRelease(mid);

八、总结

要点内容
进程资源分配单位,独立地址空间,重量级
线程CPU 调度单位,共享进程资源,轻量级
OpenHarmony 轻量系统单进程多线程,线程 = LiteOS-M 任务
线程组成私有:寄存器、PC、栈;共享:代码、数据、堆
调度机制优先级抢占 + 时间片轮转
栈管理每个线程独立栈,注意溢出风险
线程安全共享资源需临界区保护(关中断 / 互斥锁)

九、下一步

继续 Day 4:软件定时器(Timer)—— 异步事件处理机制。

http://www.jsqmd.com/news/950328/

相关文章:

  • MATLAB多变量时间序列预测工具:VAR建模、区间估计与可视化一键运行
  • 2026佛山钻石回收人群适配推荐添价收钻石回收!不同变现需求对应靠谱渠道实测解析 - 薛定谔的梨花猫
  • Illustrator脚本工具箱:10个免费神器彻底改变你的设计工作流
  • Grok 4与o3实测真相:模型能力不能只看单轮问答胜负
  • 2026年国内热门辣妹服饰品牌综合排行盘点 - 奔跑123
  • 2026吉安县青原区性价比高的广告公司:专业承接店面招牌与政企宣传制作 - 品牌2026
  • 从人工核保到秒级放保,AI工具与担保流程深度耦合的4个关键断点突破,附可复用API对接模板
  • 2024-2026美国大学生数学建模竞赛赛题分析及建模思路、获奖论文研究报告
  • Windows热键冲突终极解决方案:Hotkey Detective全面使用手册
  • 保姆级教程:用ROS和Cartographer动手搭建你的第一个2D SLAM仿真环境
  • 2026年 搬家服务公司推荐榜:专业打包与贴心搬迁,轻松避坑首选! - 品牌企业推荐师(官方)
  • 零代码单传感器循迹机器人:硬件Bang-Bang控制原理与制作
  • 【最新】电磁流量计靠谱生产工厂甄选:原厂供货可定制各类口径机型 - 品牌推荐大师
  • 义眼收费科普:义眼片收费标准是什么?义眼价格表参考|南京靓瞳奈斯义眼
  • 2026防霉剂品牌怎么选?商家推荐+用户案例+避坑指南全攻略 - 品牌优选官
  • GEO公司怎么选?geo推广哪家服务和效果好?2026年十大GEO公司/服务商盘点与头部服务商对比评测 - 互联网科技品牌测评
  • Hearthstone-Script炉石传说脚本:5分钟快速上手指南与完整使用教程
  • Vibe Coding 实战:Prompt堆砌不是关键,前置工程规范才是落地核心
  • 聚焦自干线物流自动驾驶,千曙科技与世盟物流签署合作协议 - 外贸老黄
  • C语言写的DotCode生成器,能调点形状、尺寸和文字编码,输出BMP图
  • 2026年液相色谱仪哪个品牌好?从检测精度到售后服务,企业选型必看 - 品牌推荐大师1
  • 告别Interop:用DllImport在C# .NET 6中直接调用LabVIEW生成的纯DLL
  • 2026 年高客单 IP 私域成交落地机构品牌推荐:独家测评 - 思溯深度专栏
  • 雀魂数据分析终极指南:从入门到精通的完整教程
  • 百度文库免费下载终极指南:轻松获取文档资源的完整教程
  • 基于树莓派Zero W与RPIEasy构建多传感器物联网网关
  • GEO合作前必看攻略!2026年6月GEO优化服务商最新最全排行榜:五家标杆企业深度对比后推荐指南+FAQ - 互联网科技品牌测评
  • 深度解析DXVK内存管理:高级优化与性能调优实战指南
  • 树莓派Buster系统安装VS Code:解决“找不到包”的APT源配置方案
  • RGD肽PEG磷脂 DPPE-PEG-RGD 磷脂-聚乙二醇-RGD肽反应原理