Re:Linux系统篇(四十八)线程篇 · 一:线程概念的初步认识


◆ 博主名称: 小此方-CSDN博客 大家好,欢迎来到小此方的博客。
⭐️Linux系列个人专栏: 【主题曲】Linux
⭐️此方的GitHub: github_此方
⭐️ Re系列专栏:我们思考 (Rethink) · 我们重建 (Rebuild) · 我们记录 (Record)


文章目录

  • 概要&序論
  • [一、 Linux 线程概念的理解](#一、 Linux 线程概念的理解)
    • [1.1 进程与线程的概念](#1.1 进程与线程的概念)
    • [1.2 轻量级进程模拟线程](#1.2 轻量级进程模拟线程)
      • 1.2.1多进程看到同一个虚拟地址空间
      • 1.2.2总结结论
      • [1.2.3 关于"轻量级进程执行函数"的精准认知](#1.2.3 关于“轻量级进程执行函数”的精准认知)
      • [1.2.4 核心设计抉择:为什么 Linux 不采用 PCB + TCB 方案?](#1.2.4 核心设计抉择:为什么 Linux 不采用 PCB + TCB 方案?)
      • [1.2.5 硬件 CPU 视角与"执行流"体量辨析](#1.2.5 硬件 CPU 视角与“执行流”体量辨析)
    • [1.3 概念重塑:从操作系统视角到现实比喻](#1.3 概念重塑:从操作系统视角到现实比喻)
      • [1.3.1 通俗生活比喻:社会、家庭与成员](#1.3.1 通俗生活比喻:社会、家庭与成员)
      • [1.3.2 进程与线程的本质特征汇总](#1.3.2 进程与线程的本质特征汇总)

概要&序論

  Hello大家好,我是此方 。我们已经讲完Linux的90%内容了,包括基础,权限,指令,工具,进程,文件,通信,信号, 今天开始我们将进入Linux的最后一个话题:线程 。(在此之前,通信篇第七,第一节中讲解了并发编程的初步认知。)本文讲解线程的基础概念初步认知,内容较浅显简单。

一、 Linux 线程概念的理解

1.1 进程与线程的概念

传统的操作系统教材中通常这样定义:

  • 进程 :内核数据结构 + 代码和数据,是操作系统分配资源(资源分为CPU资源和内存资源)的基本实体。
  • 线程 :在一个程序里的一个执行路线就叫做线程。更准确的定义是:线程是"一个进程内部的控制序列",是进程内部的一个执行分支,是 CPU 调度的基本单位。 一切进程至少都有一个执行线程
  • 两者都是执行流
  • 在Linux系统中,在CPU眼中,看到的线程PCB都要比传统的进程更加轻量化。
  • 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。

  从 Linux 操作系统的视角来看,线程是在进程的进程地址空间内运行的执行流 ;而从硬件 CPU 的视角来看,Linux 中的线程本质上就是轻量级进程(Light Weight Process, LWP)

1.2 轻量级进程模拟线程

1.2.1多进程看到同一个虚拟地址空间

  很多操作系统(如 Windows)为线程设计了独立的结构体(TCB)与专门的调度算法,这使得内核的设计与维护变得极其复杂。然而 Linux 选择了另一条路径------直接复用进程的 task_struct 结构体 ,复用同一套调度算法。

   以前的进程只有一个执行流,

  现在我们讲的多线程,就会在一个进程中有多个执行流,每一个执行流都有独立的task_struct。

  线程在进程内部运行,本质是在进程地址空间内运行 ,进程访问的大部分资源,都是通过地址空间访问的!地址空间是"窗口"

  创建一个"进程",共享 "窗口" ,就是将资源在分配给不同的task_struct,于是用进程,模拟出线程的本质就是划分虚拟地址与页表。

  我们以前讲的进程和我们现在讲的进程。不是冲突而是互补的。以前我们的进程是由一个PCB独占所有的资源。 于是今天我们看到的才是一个普适的真正的进程模型

1.2.2总结结论

  • 结论1: 对资源的划分,本质是对地址空间虚拟地址范围的划分。虚拟地址,就是资源的代表。

  • 结论2:函数的本质是虚拟地址空间中的代码块

    • 指令地址化:函数被编译为汇编后,其包含的每一条语句都映射到具体的虚拟地址(拥有确切的入口地址和连续的指令序列)。
    • 逻辑隔离:PC(程序计数器)通过在虚拟地址空间中顺序自增来驱动代码执行。
    • 资源划分:让不同的进程/线程去执行不同的函数,本质上就是把虚拟地址空间划分给不同的执行流去独占或共享。
  • 结论4: 单线程进程只是多线程进程的一种特殊情况。以前我们讲的进程是内核中只有一个线程的进程;现在讲的进程是由多个线程共享资源构成的整体,两者并不冲突,而是概念上的互补。

1.2.3 关于"轻量级进程执行函数"的精准认知

  在理解轻量级进程如何划分代码与数据时,初学者很容易陷入一个误区:"一个轻量级进程就是去执行某一个具体的函数。" 这种表述看似正确,但实际上不够精准。

  • 准确表述 :由于函数内部完全有可能继续调用其他函数,因此更严谨的说法是------轻量级进程拥有的只是某一个函数的入口地址,以此作为其执行起点。
  • 划分性 vs 共享性 :我们在学习这些概念时,习惯去强调轻量级进程对代码和数据的"划分性";但实际上更重要的是它们的"资源共享性"!
  • 函数执行的交集 :一个轻量级进程只有一个函数的入口地址,并不代表各个轻量级进程执行的函数之间完全没有交集。多个轻量级进程在各自的执行流中,完全可以调用同一个公共函数、访问同一块全局数据。

1.2.4 核心设计抉择:为什么 Linux 不采用 PCB + TCB 方案?

  在探讨 Linux 实现之前,我们需要回答两个核心问题:线程在内核中到底要不要被管理?其他操作系统是如何实现的?

1. 经典的"描述+组织"方案(以 Windows 为代表)

  • 先描述,再组织 :既然线程有创建、挂起、等待、调度和销毁等生命周期,操作系统内核就必须为其设计专门的数据结构进行描述。这个结构体被称为TCB(Thread Control Block,线程控制块)
  • 双重结构体系:在 Windows 等系统内部,一个进程对应一个 PCB,PCB 结构体内部包含一个指针,指向该进程所属的 TCB 链表。
  • 代价与弊端 :TCB 与 PCB 的存在使得内核数据结构极其复杂。更关键的是,线程的调度、等待、销毁算法与进程算法在逻辑上几乎完全重合。为 TCB 单独写一套算法会导致大量的内核代码冗余,系统维护成本高,且容易因复杂度提升而降低系统的健壮性。

2. Linux 的解法:完整机制复用

  • 极简哲学 :Linux 开发者认为"没有必要专门设计 TCB"。既然线程的调度与进程高度相似,不如直接复用成熟的 task_struct 结构体和调度算法。
  • 模拟的本质 :在内核代码层面,全部复用进程的底层机制。通过共享进程地址空间(mm_struct)和页表,将同一个进程的资源划分给不同的 task_struct,从而低成本地"模拟"出了线程。
  • 优势:没有复杂的 PCB+TCB 嵌套逻辑,内核更加轻量、健壮且易于维护。

1.2.5 硬件 CPU 视角与"执行流"体量辨析

  如果我们从硬件 CPU 的运行机制来看,Linux 的轻量级进程设计展现出了极高的统一性:

1. CPU 的主动与被动

  • CPU 的主动性 :硬件 CPU 通过底层的时钟中断,不断触发内核的调度算法,主动选择下一个需要执行的节点。
  • CPU 的被动性 :CPU 本身是"眼盲"的,它只管被动接收指令并执行。对 CPU 而言,它根本不关心当前运行的到底是一个传统进程还是一个轻量级进程,它只认内核链入运行队列的 task_struct。哪一个执行流需要调度,就把它的 PCB 链入运行队列即可。

2. 核心公式理解:执行流 ≤ \le ≤ 进程

  • 单线程进程 :如果给 CPU 调度的是一个单线程进程,那么此时 执行流 = 进程
  • 多线程进程 :如果给 CPU 调度的是多线程进程中的某一个线程,那么此时 执行流 < 进程(线程是进程内部的一个执行分支)。
  • 体量而非数量的比较 :需要特别强调,"执行流 ≤ \le ≤ 进程" 这句话不是数量上的比较,而是级别与体量的比较。线程继承并共享了进程的部分或大部分资源,因此单个线程作为执行流,其资源体量和调度开销都小于或等于整个进程。

1.3 概念重塑:从操作系统视角到现实比喻

  综合以上推导,我们可以对操作系统课本上的抽象定义与 Linux 的具体落地做一个清晰的对照。

1.3.1 通俗生活比喻:社会、家庭与成员

  为了更直观地理解操作系统中的资源与执行流关系,我们可以将操作系统比作社会:

  • 操作系统 = 社会:提供整体的运行环境与规则。
  • 进程 = 家庭社会分配资源的基本实体。社会在分配住房、车位、津贴等资源时,通常是以"家庭"为单位划拨的。家庭的主要目标是"过好日子"。
  • 线程 = 家庭成员:家庭内部的每一个成员(爸妈、子女)各自承担不同的任务(工作、学习、养老、赚钱)。成员们共同共享家庭的大部分资源(房子、家具),但每个人又拥有各自独占的属性(独立的身份信息、私人的私房钱/私人物品)。

1.3.2 进程与线程的本质特征汇总

基于这套轻量级进程模型,我们可以得出 Linux 下进程与线程的核心关系:

  1. 资源分配与调度的分工
    • 进程 :是承担分配系统资源的基本实体。系统以进程为单位划拨虚拟地址空间、文件描述符表等资源。
    • 线程 :是 CPU 调度的基本单位。操作系统以进程为单位申请资源,但这些申请到的资源最终都是给内部的各个线程(执行流)使用的。
  2. 资源的独占与共享
    • 进程之间 :强调资源独占,不同进程间互相隔离(只有在显式通信时才进行部分共享)。
    • 线程之间 :强调资源共享 ,同一个进程内的线程共享绝大部分代码与数据,仅保留自身执行所必需的独立栈结构CPU 寄存器上下文(部分独占)。

好的本期内容就到这里,如果对你有帮助,还不要忘记点赞三联支持。我是此方,我们下期再见。bye! Linux、C++、算法持续连载中,欢迎关注WeChat Official Account 【此方的技术栈】。

相关推荐
苍狗T2 小时前
LVS相关知识总结
linux·运维·服务器·lvs
lightqjx3 小时前
【Linux系统】基础 IO
linux·c语言·重定向·缓冲区·文件io·文件的系统调用
我星期八休息3 小时前
扩展— TCP 全连接队列与 tcpdump 抓包
linux·服务器·开发语言·前端·网络·tcp/ip·tcpdump
各类产品分享3 小时前
什么是AR智慧运维系统,主要能解决什么问题
运维·ar·ar智慧运维解决方案
RisunJan3 小时前
Linux命令-skill(发送信号给进程)
linux·运维·服务器
潘正翔3 小时前
k8s基础_kubeadm搭建k8s集群
linux·运维·docker·云原生·容器·kubernetes
Echo flower3 小时前
Docker 容器中 Puppeteer 僵尸进程排查与修复
运维·docker·容器·puppeteer
骊城英雄3 小时前
彩笔运维勇闯机器学习--逻辑回归
运维·机器学习·逻辑回归
孪生质数-4 小时前
AI 应用实践篇——让大模型真正开始工作
linux·运维·服务器·人工智能·深度学习·语言模型·llama
Splashtop高性能远程控制软件4 小时前
连锁零售多门店远程运维指南:从故障响应到批量运维的四项能力
运维·零售·远程控制·splashtop