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

【系统编程】线程简介

文章目录

  • 一、进程与线程的关系
  • 二、线程内核实现原理
    • 2.1 虚拟地址三级映射过程
    • 2.2 线程共享资源
    • 2.3 线程的非共享资源
    • 2.4 线程的状态
  • 三、线程优缺点

一、进程与线程的关系

在这里插入图片描述

1. 进程(Process)

  • 是程序在执行中的一个实例。
  • 拥有独立的地址空间(代码段、数据段、堆、栈等)。
  • 是操作系统分配资源的最小单位
  • 每个进程由操作系统管理,并配有一个进程控制块(PCB),用于保存进程状态信息。
  • 运行时常驻内存,独立于其他进程。

2. 线程(Thread)

  • 是进程中的一个执行实体,是真正“干活”的单位。
  • 是 CPU 调度和执行的最小单位
  • 通常也称为轻量级进程(Light Weight Process, LWP)
  • 一个进程可以包含一个或多个线程(多线程),至少有一个主线程。
  • 线程共享所属进程的资源(如代码段、堆、文件描述符等),但每个线程有自己的栈、程序计数器和寄存器。

3. 比较总结

比较维度进程线程
是否独立是,拥有独立的地址空间否,依附于进程
资源分配是系统分配资源的最小单位不分配资源,仅使用进程资源
调度单位不是,进程中线程才被调度是系统调度和执行的最小单位
开销大小创建、销毁、切换开销较大相对较小,效率高
共享性不共享地址空间共享进程地址空间与资源
通信方式使用 IPC 机制,开销大直接读写共享内存,开销小
  • Linux 系统中,线程 LWP 称为轻量级进程。
  • 进程:有独立的进程地址空间,有独立的 PCB,最小的资源分配单位。
  • 线程:有独立的 PCB,没有独立的进程地址空间(与其他线程共享),最小执行单位
  • 一个创建了线程的进程,本身也沦落为线程。
  • LWP号CPU 划分时间片的最小依据(最小执行单位)
    • 查看LWP号ps -Lf 进程pid

二、线程内核实现原理

2.1 虚拟地址三级映射过程

对于进程来说,相同的地址(同一个虚拟地址)在不同的进程中,反复使用而不冲突。原因是他们虽虚拟址一样,但,页目录、页表、物理页面各不相同。相同的虚拟址,映射到不同的物理页面内存单元,最终访问不同的物理页面。
但!线程不同!两个线程具有各自独立的PCB,共享同一个页目录,也就共享同一个页表物理页面。所以两个PCB共享一个地址空间

在这里插入图片描述

PCB --> 页目录(Page Directory)--> 页表(Page Table)--> 物理页框 --> 内存单元
  • 页表:可看成数组,首地址位于PCB中
  • 不同进程的同一虚拟地址,实际指向不同的物理页面 ➜ 因为有不同的页表。
  • 线程则不同,多个线程共享同一套页表,因此它们看到的虚拟地址空间是完全一致的。

在 Linux 内核中不区分“线程”与“进程”,它们都是“任务”(task),由 task_struct 结构统一管理。

  • 本质上,Linux 创建进程和线程都是通过底层 clone() 系统调用实现的。
  • fork()pthread_create() 虽然是用户接口不同,但都依赖 clone()
  • clone() 提供了一系列参数,决定子任务与父任务之间共享哪些资源。

2.2 线程共享资源

在同一个进程中的多个线程,共享以下资源,这也是线程通信效率高的根本原因:

  1. 文件描述符表

    • 所有线程共享打开的文件、socket 等资源。
  2. 每种信号的处理方式

    • 比如对 SIGINT 的处理函数,是线程共享的。
  3. 当前工作目录

    • getcwd()chdir() 在所有线程中体现一致。
  4. 用户 ID 和组 ID

    • 所有线程具有相同的用户身份(UID/GID)。
  5. 内存地址空间(包括):

    • .text 段(代码段)
    • .data 段(已初始化全局变量)
    • .bss 段(未初始化全局变量)
    • heap堆区(malloc 分配内存)
    • 共享库

2.3 线程的非共享资源

线程拥有自己独立的运行环境信息,每个线程在同一进程中也有自己独立的数据,用于保持各自的执行状态:

  1. 线程 ID(TID)

    • 每个线程有唯一 ID(在 Linux 下是一个 PID)。
  2. 处理器上下文(寄存器)与栈指针(包括内核栈)

    • 线程切换时保存的执行现场信息。
  3. 栈空间(用户栈、内核栈)

    • 每个线程都有自己的栈空间,用于函数调用和局部变量存储。
  4. errno 变量

    • 每个线程维护独立的 errno,以避免冲突。
  5. 信号屏蔽字(signal mask)

    • 控制本线程屏蔽哪些信号,与其他线程可不同。
  6. 调度优先级

    • 可为不同线程设置不同调度策略和优先级。

2.4 线程的状态

1. 准备状态(Ready)

  • 线程已被创建或刚从阻塞状态解除。
  • 各种条件都满足,只是还没被 CPU 调度执行。
  • pthread_create() 或被唤醒进入此状态。

2. 运行状态(Running)

  • 获得 CPU 时间片后进入运行状态。
  • 多核 CPU 上可能多个线程同时运行。
  • 如果不加同步机制(如锁、信号量等),可能造成竞态条件或死锁。

3. 阻塞状态(Blocked)

  • 正在等待某些外部事件或条件满足。
  • 常见阻塞原因包括:
    • 等待 I/O 响应(磁盘/网络等)。
    • 等待互斥锁(mutex)释放。
    • 等待条件变量(pthread_cond_wait)。
    • 等待信号(如 sigwait())。

4. 终止状态(Terminated)

  • 线程执行完返回、调用 pthread_exit(),或被取消(pthread_cancel())。
  • 此时线程的资源会释放或等待被 pthread_join() 回收。

三、线程优缺点

优点

  1. 提高程序并发性
  2. 开销小
  3. 数据通信、共享数据方便

缺点

  1. 库函数,不稳定
  2. 调试、编写困难、gdb不支持
  3. 对信号支持不好

Linux下由于实现方法导致进程、线程差别不是很大。

http://www.dtcms.com/a/351503.html

相关文章:

  • 【人工智能】2025年AI代理开源革命:社区驱动的智能体生态重塑未来
  • Linux--seLinux的概述
  • FRET、PLA、Co-IP和GST pull-down有何区别? 应该如何选择?
  • 原型模式系统开发中的原型分类全景:水平、垂直、抛弃式与演化式
  • nvm切换node版本之后报错,无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
  • 嵌入式C语言进阶:结构体封装函数的艺术与实践
  • IUV5G专网排障(上)
  • 支持向量机(SVM)学习笔记
  • SOME/IP服务发现PRS_SOMEIPSD_00277的解析
  • 服务器数据恢复—热备盘上线失败如何恢复数据?
  • 【Android】webview强制Crash后再自恢复设计
  • 服务器初始化
  • 影响服务器托管费用的因素​
  • ROS2 Helloworld 入门——包含完整pdf手册
  • Linux驱动开发笔记(九)——内核定时器
  • CSS 优先级:公司组织架构模型
  • css3背景线性渐变:linear-gradient
  • 基于Python+MySQL实现物联网引论课程一个火警报警及应急处理系统
  • 面向 6G 网络的 LLM 赋能物联网:架构、挑战与解决方案
  • 相机激光安全等级和人眼安全
  • 第九届MathorCup高校数学建模挑战赛-D题:钢水“脱氧合金化”配料方案的优化
  • 五自由度磁悬浮轴承同频振动抑制:从机理拆解到传递函数验证的核心方案
  • 【图像算法 - 24】基于深度学习与 OpenCV 实现人员跌倒识别系统(目标检测方案 - 跌倒即目标)
  • Baumer高防护相机如何通过YoloV8深度学习模型实现形状检测器的使用(YOLOv8 Shape Detector)
  • 无人机航拍数据集|第32期 无人机采矿区作业目标检测YOLO数据集202张yolov11/yolov8/yolov5可训练
  • GaussDB 数据库架构师修炼(十八) SQL引擎-计划管理-SPM
  • Windows MCP 安装教程:让 AI 代理与 Windows 系统无缝交互
  • plantsimulation知识点 RGV小车前端与后端区别
  • 数字营销岗位需要具备的能力有哪些
  • 洛谷 P12332 题解