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

内核编程十一:进程的数据结构

在Linux内核中,task_struct 是用于描述进程的核心数据结构,存储了进程的所有关键信息,包括进程ID、状态、调度信息、内存管理信息、文件描述符等。每个进程在内核中都对应一个 task_struct 结构体。


1. task_struct 的基本定义

task_struct 结构体的定义位于 include/linux/sched.h 头文件中。如下图所示,通过双向循环链表的方式将所有进程关联起来。

此结构体非常庞大, task_struct结构体中又包含了非常多的子结构体

由于task_struct内容较为庞大,这里列出部分关键字段: 

struct task_struct {
    volatile long state;         // 进程状态 (TASK_RUNNING 等)
    struct list_head tasks;      // 进程链表 (所有进程通过该字段连接)
    pid_t pid;                   // 进程 ID
    pid_t tgid;                  // 线程组 ID (线程与主线程共享)
    struct mm_struct *mm;        // 进程的内存管理信息
    struct thread_struct thread; // 进程的 CPU 相关信息 (寄存器等)
    struct list_head children;   // 子进程链表
    struct task_struct *parent;  // 父进程
    struct files_struct *files;  // 进程打开的文件信息
    struct fs_struct *fs;        // 进程的文件系统信息
    struct signal_struct *signal;// 进程的信号处理信息
    struct sched_entity se;      // 进程的调度信息
};

2. task_struct 主要字段解析

(1)进程状态

  • state:表示进程当前的状态,可能的取值包括:

    #define TASK_RUNNING       0  // 运行态或就绪态
    #define TASK_INTERRUPTIBLE 1  // 可中断睡眠状态
    #define TASK_UNINTERRUPTIBLE 2 // 不可中断睡眠状态
    #define TASK_STOPPED       4  // 进程已停止
    #define TASK_TRACED        8  // 进程被调试

(2)进程的标识

  • pid:进程 ID,是 Linux 内核唯一标识一个进程的数值。

  • tgid:线程组 ID,同一进程的多个线程共享相同的 tgid,而主线程的 pid == tgid

(3)进程调度

  • struct sched_entity se:保存进程的调度信息,如优先级、时间片等,供 CFS(Completely Fair Scheduler,完全公平调度器) 使用。

(4)进程的内存管理

  • struct mm_struct *mm:指向进程的内存管理结构,包含代码段、数据段、堆、栈等信息。

    • mm->pgd:页全局目录(Page Global Directory),用于地址转换。

    • mm->mmap:存储该进程的虚拟内存区域(VMA,Virtual Memory Area)。

  • struct fs_struct *fs:文件系统信息,比如 cwd(当前工作目录)。

(5)进程的关系

  • struct task_struct *parent:指向父进程。

  • struct list_head children:指向该进程创建的子进程列表。

(6)进程的文件管理

  • struct files_struct *files:保存进程打开的所有文件的描述符信息,如 fd

3.线程

task_struct 既表示进程,也表示线程
Linux 内核不区分进程和线程,所有的执行实体(tasks)都是 task_struct 结构体的一个实例。

线程和进程的主要区别在于:

  • 进程:有独立的地址空间(mm_struct)。
  • 线程:共享同一个地址空间(mm_struct),但 task_struct 依然是独立的。
  • Linux 线程创建时,调用 clone() 系统调用,最终创建一个新的 task_struct,但其 mm_struct 指针与父线程共享。

在Linux中,线程和进程的主要数据结构都是 task_struct,并不是 thread_info。

task_struct 是 Linux 内核中表示进程和线程的主要数据结构,而 thread_info 只是一个与 task_struct 关联的辅助结构,不能直接等同于线程的数据结构。


4. 进程的创建与 task_struct

Linux 创建进程主要通过 fork()clone()kernel_thread(),内核会:

  1. 调用 copy_process()

    • 为新进程分配 task_struct

    • 复制父进程的部分信息,如 pidmmfiles

    • 根据 clone 标志决定哪些资源共享(如文件、地址空间)。

  2. task_struct 插入进程链表

    • task_struct 通过 tasks 链接到 init_task 全局变量,实现进程管理。


5. task_struct 在内存中的存放

在 Linux 早期版本,task_struct 直接存放在 内核态栈 的底部,但由于 task_struct 变得越来越大,现代 Linux 将其单独分配在 slab 内存池 中。


http://www.kler.cn/a/613835.html

相关文章:

  • springboot 实现base64格式wav转码并保存
  • 第 4 章 | Solidity安全 权限控制漏洞全解析
  • GelSight视触觉3D显微系统在透明材料检测中的应用
  • Go红队开发—CLI框架(二)
  • 网络华为HCIA+HCIP 防火墙
  • SpringBoot第一节
  • 当编程语言有了人格
  • HCIP(TCP)(2)
  • 「HTML5+Canvas实战」星际空战游戏开发 - 纯前端实现 源码即开即用【附演示视频】
  • 2025 年中国家电零售与创新趋势解析:以旧换新国补激活需求,AI 技术渗透至研发、供应链、营销
  • 优秀的 React 入门开源项目推荐
  • 蓝桥杯第 12 天 109 国赛第一题 分考场(干了一个小时的题)
  • CSS3学习教程,从入门到精通,CSS3 定位布局页面知识点及案例代码(18)
  • C++类与对象的第一个简单的实战练习-3.24笔记
  • 20250328易灵思FPGA的烧录器FT4232_DL的驱动安装
  • Citus源码(1)分布式表行为测试
  • 【Mac】npm error Error: EACCES: permission denied, mkdir‘/Users/...
  • 第十三届蓝桥杯国赛电子类单片机学习记录(客观题)
  • HCIP笔记整理
  • 2025年春招-Linux面经