无锡做网站6,可拖拽式网站建设,网店代运营公司哪家好,wordpress建站网页无法运目录 操作系统中
运行状态
阻塞状态
进程状态转换 Linux系统中
查看进程状态
深度睡眠状态
T 暂停状态
Z 僵尸状态 孤儿状态
文章手稿 xmind: 引言
介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例#xff0c;详细说明进程的各种状态、转换…目录 操作系统中
运行状态
阻塞状态
进程状态转换 Linux系统中
查看进程状态
深度睡眠状态
T 暂停状态
Z 僵尸状态 孤儿状态
文章手稿 xmind: 引言
介绍系统中的进程状态及其管理方式。将通过结合操作系统原理和实际代码示例详细说明进程的各种状态、转换过程以及处理方法。 操作系统中
一个进程通常有三种状态 就绪状态Ready表示进程已经具备运行所需要的一切条件只需要等待CPU的分配就可以运行。进程处于就绪状态时通常会被添加到就绪队列等待调度器分配CPU资源。运行状态Running表示进程正在被CPU执行。处于运行状态的进程正在使用CPU进行计算或其他操作。阻塞状态Blocked表示进程因为某些原因暂时无法继续执行需要等待一些特定条件的解除之后才能继续运行。例如当进程等待I/O操作完成或者等待某个资源可用时会转入阻塞状态。进程在阻塞状态时通常会被移动到阻塞队列中等待条件的满足。 我们下面将对运行阻塞和阻塞挂起进行介绍~ 运行状态 进程只要在运行队列中就叫做 运行态。 阻塞状态 关于进程 ① 一个进程使用资源的时候可不仅仅是在申请 CPU 资源 ② 进程可能会申请其它资源磁盘、网卡、显卡显示器资源…… 如果我们申请 CPU 资源无法暂时无法得到满足这就需要排队的 运行队列 。那么如果我们申请其他慢设备的资源呢是需要排队的task_struct 在进程排队。 当访问某些资源磁盘网卡等如果该资源暂时没有准备好或者正在给其他进程提供服务那么此时
① 当前进程要从 runqueue 中逐出。 ② 将当前进程放入对应设备的描述结构体中的waitqueue 。
进程状态看PCB在哪个队列
内存不足了操作系统就会把 该进程的代码和数据置换到磁盘上进行 进程挂起。
进程状态转换
进程状态的转换可以通过以下示例说明
#include stdio.h
#include unistd.hint main() {while (1) {printf(进程[%d]正在运行...\n, getpid());sleep(1); // 模拟阻塞状态}return 0;
}通过运行上述代码并观察进程状态可以理解进程在不同状态之间的转换过程。
三种状态的图示如下 Linux系统中
进程状态用整数表示这些整数存储在进程的task_struct结构体中。常见的进程状态包括运行R、睡眠S、磁盘睡眠D、停止T、死亡X、僵尸Z和孤儿进程。
进程状态一览
状态代码状态名称描述R运行Running进程正在运行或在运行队列中等待S睡眠Sleeping进程在等待某事件完成可被信号唤醒D磁盘睡眠Disk Sleep进程在等待I/O操作完成不可被信号唤醒T停止Stopped进程被暂停可通过信号恢复X死亡Dead进程已终止从进程列表中移除Z僵尸Zombie进程已退出父进程尚未读取其状态孤儿Orphan父进程已退出被init进程收养
查看进程状态
使用ps aux或ps axj命令可以查看系统中进程的状态。例如
ps aux
ps axj这些命令输出的状态字段展示了进程当前的状态。 背后的原因让人暖心cpu太快了print显示器等待的时间在他看来就是在sleep了 深度睡眠状态 这个D状态我们就不模拟了……可能会把我的机子磁盘打满害怕.dog T 暂停状态
比如看视频听音乐下载都会有暂停。当你点击暂停的时候下载对应的代码就不跑了此时这个进程你就可以认为是暂停状态。 再比如说我们调试程序让程序打断点之后让程序运行起来程序在打断点处停住的时候是将进程暂停了所以你在gdb 调试或在 VS 下调试时你会发现程序会停下来这就是暂停。 是进程挂起的一种。 我们可以先来看一下kill 接下来可以来尝试一下;
$ kill -19 4026就会发现 gdb下的暂停状态测试一下
$ gdb process # 进入gdb调试
(gdb) l # 查看代码
(gdb) b 9 # 打断点
q 回车 # 退出 Z 僵尸状态
僵尸状态当一个 Linux 中的进程退出的时候一般不会直接进入 X 状态死亡资源可以立马被回收而是进入 Z 状态。 为什么呢~ 进程为 Z 状态就是为了维护退出信息可以让父进程或者 OS 读取记录的退出信息会写入 test_struct。 以下是创建僵尸进程的代码示例
#include stdio.h
#include stdlib.h
#include unistd.hint main() {pid_t id fork();if (id 0) {perror(fork);return 1;} else if (id 0) { // 子进程printf(子进程[%d]开始运行...\n, getpid());sleep(5);printf(子进程[%d]退出...\n, getpid());exit(0);} else { // 父进程printf(父进程[%d]正在睡眠...\n, getpid());sleep(30); // 父进程延迟回收子进程}return 0;
}我们可以写一个监控脚本来看一下~
while :; do ps axj | head -1 ps axj | grep mytest | grep -v grep; sleep 1; echo ###### ; done 在另一个终端中运行ps命令可以看到子进程进入僵尸状态。 僵尸进程的危害
僵尸进程虽然不再运行但它们仍然占用系统资源如进程控制块task_struct。如果父进程不及时回收子进程会导致系统资源浪费甚至内存泄漏。
避免僵尸进程
可以通过以下方式 父进程及时调用wait()或waitpid()回收子进程。使用信号处理机制在子进程退出时通知父进程进行回收。 孤儿状态
孤儿进程父亲没了bushi
即父进程先退出了子的父就变成1 号进程了相当于被os领养了
测试一下
#include stdio.h
#include unistd.h
#include stdlib.hint main(void) {pid_t id fork();if (id 0) {// childint cnt 5;while (1) { // 死循环孩子进程就不退了printf(我是子进程我还剩下 %ds\n, cnt--);sleep(1);}printf(我是子进程我已经变僵尸了等待被检测\n);exit(0);}else {// fatherint cnt 3;while (cnt) {printf(我是父进程我: %d\n, cnt--);sleep(1);}exit(0);}
} 监控一下 while :; do ps axj | head -1 ps axj | grep mytest | grep -v grep; sleep 1;echo ######;done我们可以top看一下1究竟是什么 ❓ 疑问父进程退出为什么父进程没有变成僵尸我们怎么没有看到父进程 为Z 那是因为父进程的父进程是bash 它会自动回收它的子进程也就是这里的父进程。这里之所以没有看到父进程变成僵尸是因为被 bash 回收了 z-x 的状态很快所以你没看到。那为什么刚才我自己代码中的父进程创建的子进程父进程没有回收子进程呢那是因为你的代码压根就没有写回收所以你的子进程就没有回收。 那我们怎么暂停呢ctrlc 只能干掉前台进程
所以孤儿进程就要用到我们的杀进程kill -9来暂停啦 文章手稿