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管理起来
};
