🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录
2. Linux 中的 PCB:task_struct 结构体
1. 进程与 PCB 的核心概念
进程(Process)
- 是程序的动态执行实例,包含代码、数据、堆栈、寄存器状态和资源(文件、内存、信号等)。
- 操作系统通过**进程控制块(PCB)**管理进程的所有信息。
PCB(Process Control Block)
- 操作系统中每个进程的元数据集合,在 Linux 中具体实现为
task_struct
结构体。 - 核心作用:保存进程状态,支持进程调度、资源分配和上下文切换。
2. Linux 中的 PCB:task_struct
结构体
Linux 内核通过 task_struct
完整描述一个进程/线程,其关键字段如下:
字段类别 | 关键成员 | 作用 |
---|---|---|
标识信息 | pid_t pid | 进程唯一标识符(PID) |
pid_t tgid | 线程组 ID(主线程 PID) | |
状态与调度 | volatile long state | 进程状态(运行、就绪、阻塞等) |
int exit_state | 终止状态(僵尸进程标记) | |
struct sched_entity se | 调度实体(权重、优先级、时间片) | |
内存管理 | struct mm_struct *mm | 指向进程虚拟内存描述符(地址空间、页表等) |
文件系统 | struct files_struct *files | 打开的文件描述符表 |
信号处理 | struct signal_struct *signal | 信号处理函数表 |
进程关系 | struct task_struct *parent | 父进程指针 |
struct list_head children | 子进程链表 | |
时间统计 | u64 utime , u64 stime | 用户态和内核态 CPU 时间 |
3. 进程生命周期与状态转换
进程状态定义(state
字段)
TASK_RUNNING
:进程正在运行或就绪(等待 CPU 调度)。TASK_INTERRUPTIBLE
:可中断睡眠(等待资源或信号唤醒)。TASK_UNINTERRUPTIBLE
:不可中断睡眠(等待必须完成的硬件操作)。__TASK_STOPPED
:进程被暂停(如收到SIGSTOP
信号)。EXIT_ZOMBIE
:僵尸状态(进程已终止,但父进程未回收资源)。EXIT_DEAD
:最终终止状态。
典型生命周期流程
创建 (fork) → 就绪 (TASK_RUNNING) → 运行 →
→ 阻塞 (TASK_INTERRUPTIBLE/UNINTERRUPTIBLE) → 唤醒 → 就绪 →
→ 终止 (exit) → 僵尸 (EXIT_ZOMBIE) → 父进程回收 (wait) → EXIT_DEAD
4. 进程创建与管理机制
关键系统调用
fork()
:通过**写时复制(COW)**克隆父进程,创建子进程。- 子进程复制父进程的
task_struct
、内存映射和文件表(引用计数增加)。
- 子进程复制父进程的
execve()
:加载新程序到进程空间,重置代码段和数据段。wait()
/ waitpid():父进程回收子进程资源,避免僵尸进程。
代码示例:进程创建
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = fork();
if (pid == 0) { // 子进程
execl("/bin/ls", "ls", "-l", NULL);
} else { // 父进程
wait(NULL); // 等待子进程结束
}
return 0;
}
5. 进程调度机制
调度策略(policy
字段)
SCHED_NORMAL
:普通进程的完全公平调度(CFS)。SCHED_FIFO
/SCHED_RR
:实时进程的先进先出或轮转调度。SCHED_BATCH
/SCHED_IDLE
:低优先级后台任务。
调度实体(sched_entity
)
- 包含
vruntime
(虚拟运行时间),用于 CFS 计算进程优先级。 - 通过红黑树组织就绪队列,选择
vruntime
最小的进程执行。
6. 进程间通信(IPC)与资源共享
IPC 机制
- 信号(Signals):通过
kill()
或键盘事件(如 Ctrl+C)发送信号。 - 管道(Pipes):单向数据流,基于文件描述符通信。
- 共享内存(Shared Memory):通过
shmget()
创建共享内存区域。 - 信号量(Semaphores):同步对共享资源的访问。
线程与轻量级进程(LWP)
- Linux 线程通过
clone()
系统调用实现,共享地址空间和文件描述符。 - 每个线程拥有独立的
task_struct
,但tgid
指向主线程 PID。
7. 进程监控与调试工具
常用命令
ps
:查看进程状态、PID 和资源占用。ps aux | grep nginx # 查找 nginx 相关进程
top
/ htop:实时监控进程 CPU/内存使用。strace
:跟踪进程的系统调用。strace -p <PID> # 跟踪正在运行的进程
gdb
:调试进程内存和堆栈。gdb -p <PID> # 附加到运行中的进程
查看 /proc
文件系统
cat /proc/<PID>/status # 查看进程详细状态
ls /proc/<PID>/fd/ # 查看进程打开的文件描述符
8. 核心机制总结
机制 | 实现方式 | 内核数据结构 |
---|---|---|
进程标识 | PID 与命名空间(namespace) | pid_namespace |
状态管理 | state 字段与调度器交互 | task_struct |
资源隔离 | 虚拟内存(mm_struct )与文件描述符表 | mm_struct , files_struct |
进程间通信 | 信号、管道、共享内存等 | signal_struct , 管道缓冲区 |
调度公平性 | CFS 算法与 vruntime 计算 | sched_entity 红黑树 |
深入理解建议
- 阅读内核源码:
task_struct
定义位于include/linux/sched.h
。 - 编写内核模块:通过
procfs
或sysfs
接口输出进程信息。 - 性能优化:分析进程调度延迟(
/proc/sched_debug
)和内存泄漏(valgrind
)。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙