
目录前言Part1. 进程状态Part1.1. 运行状态Part1.2. 阻塞状态Part1.3. 挂起状态Part1.4. 内核链表Part1.5. Linux进程状态标识Part1.6. 僵尸进程Part1.7. 进程缓存Part1.8. 补充知识点Part2. 进程状态流转简图Part3. 结语前言这篇文章我们来进一步认识进程的状态以及之间的转化接下来来跟随小编的视角来认识一下进程的概念吧。lets go!!!!!!!!Part1. 进程状态进程状态是PCB中的属性用来表征进程当前的情况状态之间可以相互转化。Part1.1.运行状态只要进程在调度队列中就属于运行状态。不一定正在CPU上跑只要被放进CPU调度队列就标记为R运行态。Part1.2. 阻塞状态进程等待某种外部条件/硬件资源就绪例如键盘输入、磁盘IO、网卡数据。典型场景scanf / cin等待用户输入。进程不在CPU调度队列挂到对应硬件的等待队列条件就绪后进程会被重新放回CPU调度队列。Part1.3. 挂起状态内存不足时操作系统会把暂时用不到、处于阻塞状态的进程把进程数据换出到磁盘swap分区释放物理内存。等到内存资源充足再把进程换回内存。Part1.4. 内核链表//Linux内核不使用普通指针管理task_struct而是使用通用双向链表list_head。 struct list_head { struct list_head *next, *prev; }; //task_struct内部包含list_head links成员。 //links是链表节点不是task_struct本身。 //通过链表成员地址反向算出整个task_struct结构体起始地址 #define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type,member))) //一个task_struct可以嵌入多个list_head成员让同一个进程节点挂入多条不同链表运行队列、等待队列等。Part1.5. Linux进程状态标识标识 含义R 运行态在CPU调度队列S 浅睡眠可被信号唤醒T 暂停调试暂停ctrlzD 深度睡眠磁盘IO等待不能被信号杀死X 死亡进程彻底释放Z 僵尸进程进程已经退出PCB保留等待父进程读取退出信息D状态深度睡眠例子进程向磁盘写大量数据等待磁盘IO完成。此时内存紧张就算执行kill -9也无法杀掉D态进程IO没有完成操作系统不能随意杀掉进程防止数据丢失。Part1.6. 僵尸进程子进程执行完毕不能直接彻底释放PCB。父进程需要读取子进程的执行结果main返回值、信号信息信息保存在子进程PCB中。• 如果父进程一直不调用wait/waitpid接收子进程退出信息子进程就一直保持僵尸Z状态。• 僵尸进程PCB不会被操作系统自动回收必须父进程来读取才会释放PCB。僵尸进程类似“内存泄漏”PCB资源一直占用。Part1.7.进程缓存进程退出的时候不会把task_struct结构体完全释放还给内存。把废弃的PCB结构体放到一个unused链表缓存起来。当后续需要新建进程时直接复用缓存中的PCB只做初始化。省去频繁申请、释放内存的开销提升创建进程效率。Part1.8. 补充知识点1. 进程退出普通资源操作系统会自动回收僵尸进程PCB不会自动回收。2.挂起状态对用户不可见由操作系统内部完成换入换出。3.X代表前台进程X后台进程。Part2. 进程状态流转简图1.新建进程 → R运行状态进入CPU调度队列2.R运行态 → S阻塞态进程等待IO/外设离开CPU调度队列进入对应设备等待队列3.S阻塞态 → R运行态等待的资源就绪进程被放回CPU调度队列4.R运行态 → T暂停态收到暂停信号停止调度5.R运行态 → Z僵尸态子进程执行完毕等待父进程读取退出状态6.Z僵尸态 → X死亡态父进程调用wait读取退出信息PCB彻底释放7.内存紧张S阻塞进程 → 挂起数据换到swap磁盘内存充足后换回内存回到S状态。Part3. 结语这篇文章我们认识并知道了进程状态及其之间的转化接下来小编还会带来更多Linux相关的知识敬请期待~最后祝大家可以春风得意马蹄疾一日看尽长安花最后的最后要是觉得本文还可以的话可以点点赞关注小编一波谢谢大家~