Linux:进程 vs 线程:资源共享与独占全解析(线程四)

一、核心结论

进程是资源分配的基本单位,线程是调度执行的基本单位。二者的核心区别在于 "资源是否共享"------ 进程间完全独立,线程共享进程的虚拟地址空间及大部分资源,仅独占少量执行上下文相关资源

二、资源共享清单(线程共享的进程资源)

同一进程内的所有线程共享以下资源,这是线程通信便捷、创建成本低的核心原因:

  1. 虚拟地址空间:代码段(Text Segment)、数据段(Data Segment)、堆、共享库、mmap 映射区域
  2. 文件资源:文件描述符表、信号处理方式(SIG_IGN、SIG_DFL 或自定义处理函数)
  3. 进程环境:当前工作目录、用户 ID(UID)、组 ID(GID)
  4. 其他资源:信号量、消息队列、共享内存等进程级通信机制

共享资源的实际意义

  • 线程可直接访问全局变量、堆内存,无需跨进程通信;
  • 打开的文件可被所有线程复用,无需重复打开;
  • 共享库仅加载一次,所有线程共享代码和数据,节省内存

三、资源独占清单(线程私有资源)

为保证独立执行,线程独占以下与执行上下文相关的资源:

  1. 线程 ID(tid):内核层面的唯一标识,通过gettid()获取
  2. 执行上下文:CPU 寄存器(程序计数器 PC、栈指针 SP 等),线程切换时需保存和恢复
  3. 栈空间:主线程栈在虚拟地址空间的栈区,子线程栈在共享区(通过 mmap 分配),默认大小通常为 8MB,不可动态增长
  4. 线程局部数据:errno 变量、信号屏蔽字、调度优先级、线程私有存储(TLS);
  5. 线程属性:栈大小、分离状态、调度策略等

独占资源的实际意义:

  • 线程栈私有避免函数调用栈数据冲突
  • 信号屏蔽字允许线程独立控制接收哪些信号
  • 调度优先级让线程可获得不同的 CPU 时间片

四、进程与线程的核心区别对比表

对比维度 进程(Process) 线程(Thread)
核心角色 资源分配的基本单位 调度执行的基本单位
资源独立性 高(独立虚拟地址空间、文件描述符等) 低(共享进程资源,仅独占执行上下文)
上下文切换成本 高(需切换页表、地址空间、寄存器、缓存) 低(仅切换寄存器和栈,页表和缓存不变)
崩溃影响范围 仅自身,不影响其他进程 整个进程及所有线程都会崩溃
通信方式 复杂(管道、消息队列、共享内存等) 简单(直接访问全局变量、堆内存)
创建成本 高(需分配虚拟地址空间、页表、文件资源) 低(仅需初始化执行上下文和私有栈)
内核实现(Linux) 独立task_struct + 独立mm_struct 独立task_struct + 共享mm_struct

五、关键场景验证:进程切换 vs 线程切换

1. 进程切换流程:

  1. 保存当前进程的task_struct状态(寄存器、页表指针等)
  2. 切换页表(更新 CR3 寄存器指向新进程的页目录)
  3. 刷新 TLB(快表),因为页表已改变
  4. 恢复新进程的task_struct状态,执行新进程

2. 线程切换流程:

  1. 保存当前线程的寄存器和栈指针
  2. 恢复目标线程的寄存器和栈指针
  3. 无需切换页表和刷新 TLB,因为共享mm_struct
  4. 执行目标线程

性能差异:

线程切换的成本远低于进程切换,尤其是 TLB 刷新的开销 ------TLB 是虚拟地址到物理地址的缓存,刷新后需重新建立映射,会导致内存访问效率暂时下降

六、新手常见误区

  1. 误区:线程崩溃只影响自身→纠正:线程共享进程地址空间,一个线程的非法操作(如野指针)会触发信号,导致整个进程终止
  2. 误区:线程栈和进程栈一样可动态增长→纠正:子线程栈通过 mmap 分配,大小固定,用尽会触发栈溢出
  3. 误区:进程和线程是完全独立的概念→纠正:Linux 中线程是轻量级进程,二者均用task_struct描述,仅资源共享方式不同

七、总结

  • 进程与线程的核心区别在于 "资源分配" 和 "调度执行" 的职责划分
  • 线程共享进程的大部分资源,仅独占执行上下文相关资源,这是其轻量级的本质
  • 理解资源共享与独占特性,是后续学习线程同步、通信的基础

下一篇将讲解线程控制的核心操作:线程创建与终止,不见不散啦!!

相关推荐
qq_12498707533 小时前
基于springboot的竞赛团队组建与管理系统的设计与实现(源码+论文+部署+安装)
java·vue.js·spring boot·后端·信息可视化·毕业设计·计算机毕业设计
瑞雪兆丰年兮3 小时前
[从0开始学Java|第五天]Java循环高级综合练习
java·开发语言
J_liaty3 小时前
SpringBoot 自定义注解实现接口加解密:一套完整的多算法方案
java·spring boot·算法
yuanjj883 小时前
域格移芯平台模块Linux下RNDIS、ECM拨号及网口名称修改
linux·rndis·ecm·ttyacm
zzzsde3 小时前
【Linux】进程(2):进程概念与操作理解
linux·运维·服务器
郝学胜-神的一滴3 小时前
Linux Socket模型创建流程详解
linux·服务器·开发语言·网络·c++·程序人生
zhengfei6113 小时前
踪有趣的 Linux(和 UNIX)恶意软件。提交 PR
java·数据库·mysql
「QT(C++)开发工程师」3 小时前
C++ 观察者模式
java·c++·观察者模式
天才奇男子3 小时前
《深度解析HAProxy七层代理:原理、配置与最佳实践》
linux·运维·微服务·云原生