进程调度及文件系统的管理

runqueue

cpp 复制代码
// linux-2.6.11/kernel/sched.c
struct runqueue {
    // O(1) 核心:active/expired 双数组
    prio_array_t *active;            // 时间片未用完(活跃)
    prio_array_t *expired;           // 时间片用完(过期)
    prio_array_t arrays[2];          // 实际存储:arrays[0]=active, arrays[1]=expired

}

prio_array

cpp 复制代码
/* 经典 O(1) 调度器优先级数组 */
struct prio_array {
    // 当前队列中就绪进程总数
    unsigned int nr_active;

    // 优先级位图:每一位代表对应优先级是否有就绪进程
    // 只要某bit置1,说明该优先级链表不为空
    unsigned long bitmap[BITMAP_SIZE];

    // 140 条双向链表头,每个优先级一条队列
    struct list_head queue[MAX_PRIO];
};
prio_array
├── nr_active  // 总就绪任务数
├── bitmap[5]  // 140位位图,快速定位最高优先级
└── queue[140] // 每个优先级一条链表
     queue[0]  -> 实时高优进程链表
     queue[99] -> 实时低优进程链表
     queue[100]~queue[139] -> 普通进程链表

优先级越高分到的时间片也越多

task_struct

cpp 复制代码
// 进程控制块 PCB (Linux 标准完整版)
struct task_struct {
    // 1. 进程基本信息
    pid_t pid;                // 进程ID
    pid_t ppid;               // 父进程ID
    char comm[16];            // 进程名称
    long state;               // 进程状态:运行R/可中断睡眠S/不可中断睡眠D/停止T/僵尸Z

    // 2. 退出状态
    int exit_code;            // 进程退出码(0=正常,非0=错误)
    int exit_signal;          // 导致进程终止的信号

    // 3. O(1)调度 + Nice优先级
    int nice;                 // 用户优先级 -20 ~ 19 用户只能使用0-19
    int static_prio;          // 静态优先级 100~139 默认为120,其值为120+nice
    int prio;                 // 动态优先级,OS会微调
    unsigned int time_slice;  // 时间片
    struct list_head run_list;// 调度队列链表节点 

    // 4. 内存管理
    struct mm_struct *mm;     // 进程自身地址空间(用户进程)
    struct mm_struct *active_mm; // 当前CPU正在使用的地址空间

    // 5. 文件系统(Linux标准)
    struct fs_struct *fs;     // 文件系统上下文:root、pwd、umask
    struct files_struct *files; // 打开文件描述符表
};

mm_struct

cpp 复制代码
// 进程虚拟内存描述符(内核真实版)
struct mm_struct
{
    // 1.代码段 【包含:正文段.text + 常量区.rodata】
    unsigned long start_code;
    unsigned long end_code;

    // 2.数据段(.data) 已初始化全局/静态变量
    unsigned long start_data;
    unsigned long end_data;

    // 3.BSS段(.bss) 未初始化全局/静态变量
    unsigned long start_bss;
    unsigned long end_bss;

    // 4.堆区:向上生长(低地址→高地址)
    unsigned long start_heap;
    unsigned long brk;

    // 5.共享区(内核真名:mmap映射区)
    // 存放动态库.so、共享内存、mmap文件映射
    unsigned long mmap_base;

    // 6.用户栈:向下生长(高地址→低地址)
    unsigned long start_stack;

    // 引用计数:线程/进程共享地址空间使用
    int count;
};

list_head

cpp 复制代码
// 内核通用双向循环链表头节点结构
struct list_head {
    // 前驱节点指针
    struct list_head *prev;
    // 后继节点指针
    struct list_head *next;
};

files_struct

cpp 复制代码
// 进程打开文件描述符表管理结构
// 每个进程/线程组一份,记录当前打开的所有文件、标准输入输出、文件描述符映射
struct files_struct
{
    // 引用计数:多线程共享该files_struct时计数
    atomic_t count;

    // 文件描述符关闭时的执行标志
    int close_on_exec_fd;

    // 文件描述符数组:存放每个fd对应的file结构体指针
    // fd_array[0] = 标准输入
    // fd_array[1] = 标准输出
    // fd_array[2] = 标准错误
    struct file **fd_array;

    // 当前已分配的最大文件描述符
    unsigned int max_fds;

    // 当前未分配的最小文件描述符(分配fd时从这里开始找)
    unsigned int next_fd;

    // 位图:标记哪些fd在执行exec时需要自动关闭
    unsigned long *close_on_exec;
    // 位图:标记哪些fd已经被占用
    unsigned long *open_fds;
};

file

cpp 复制代码
// 内核打开文件实例结构体(精简核心版)
struct file
{
    // 文件操作函数集:read/write/ioctl/llseek 等
    struct file_operations *f_op;

    // 指向该文件对应的目录项(关联文件名、路径)
    struct dentry *f_dentry;

    // 文件打开模式:只读/只写/读写、追加、非阻塞等
    fmode_t f_mode;

    // 文件当前偏移量(读写位置指针)
//记录当前读到文件哪个位置,每个进程打开同一个文件可以拥有各自独立的偏移量。
    loff_t f_pos;

    // 引用计数
    atomic_t f_count;

    // 私有数据,给文件系统/驱动自己用
    void *private_data;
};

fs_struct

cpp 复制代码
// 前向声明
struct vfsmount;
struct dentry;

// 内核标准 path 结构体:定位一个文件/目录的完整路径信息
struct path
{
    struct vfsmount *mnt;    // 文件系统挂载描述符:标识该目录属于哪个挂载点,内部会指向分区的超级块
    struct dentry *dentry;   // 目录项对象:标识具体的目录/文件节点
};

// 进程文件系统上下文结构
// 保存进程根目录、当前工作目录、权限掩码等全局文件环境
struct fs_struct
{
    int count;               // 引用计数:多线程共享该fs_struct时的计数
    struct path root;         // 进程根目录路径,chroot系统调用修改此处
    struct path pwd;         // 进程当前工作目录路径,cd命令本质修改此处
    struct path altroot;     // 备用根目录,内核备用路径机制使用
    umode_t umask;           // 文件创建权限掩码,控制新建文件默认权限
    umode_t fsumask;         // 目录创建权限掩码,专门控制新建目录默认权限
};

dentry

cpp 复制代码
// 目录项:VFS 文件名缓存、目录树结构核心
struct dentry
{
    atomic_t        d_count;     // 引用计数,标记是否被引用、不可回收
    unsigned int    d_flags;     // dentry 状态标志

    struct inode   *d_inode;     // 关键:指向该文件/目录对应的inode
    struct dentry  *d_parent;    // 父目录的dentry

    struct qstr     d_name;      // 文件名(名字、长度、hash)

    // 内核链表关键节点
    struct list_head d_child;    // 挂到父目录的子项链表
    struct list_head d_subdirs;  // 自己下属的所有子目录链表
    struct list_head d_lru;      // LRU链表,闲置时等待内存回收
    struct list_head d_alias;    // 硬链接别名链表(一个inode多个文件名)

    struct super_block *d_sb;    // 所属文件系统超级块
};

inode

cpp 复制代码
struct inode
{
    umode_t i_mode;        // 文件类型+权限
    nlink_t i_nlink;       // 硬链接计数
    uid_t i_uid;           // 所有者用户ID
    gid_t i_gid;           // 所属组ID
    loff_t i_size;         // 文件大小

    // 时间戳
    struct timespec i_atime;  // 访问时间
    struct timespec i_mtime;  // 修改内容时间
    struct timespec i_ctime;  // 修改元数据时间

    //  老式课本标准磁盘块指针数组
     //存储磁盘块号
    unsigned long i_block[15];  

    struct super_block *i_sb; // 指向所在文件系统的超级块
    struct list_head i_alias;   // 硬链接dentry别名链表
    //同一个inode的硬链接文件名都会被i_alias管理起来
};
相关推荐
许泽宇的技术分享2 小时前
别再把 AI Agent 当“会聊天的脚本”:Hermes Agent 源码级拆解(架构、框架、实战、趋势,一文吃透)
java·linux·网络
HalvmånEver2 小时前
MySQL事务(一)
linux·数据库·学习·mysql
%KT%2 小时前
Agent开发:自动查天气+景区推荐
linux·数据库·php
Yupureki2 小时前
《Linux网络编程》9.数据链路层原理
linux·运维·服务器·网络
顶点多余2 小时前
Socket编程实现UDP通信
linux·网络协议·udp
切糕师学AI2 小时前
Remmina:Linux 平台的全能远程桌面客户端详解
linux·运维·远程控制·远程桌面·remmina
dualven_in_csdn2 小时前
【assist】 需要用到的方法
linux·运维·服务器
minji...2 小时前
Linux 网络基础(二)HTTP协议,域名,URL,URI,认识HTTP的请求和响应
linux·服务器·网络·网络协议·http·tcp
萑澈3 小时前
Linux内核安全态势报告:2021-2026年高危漏洞演进与深度技术分析
linux·ubuntu