推荐网站制作公司,wordpress引用php,中小企业门户网站建设策略,明港seo公司目录 1.进程状态1.1 阻塞1.2 挂起 2. 进程状态2.1 运行状态-R进一步理解运行状态 2.2 睡眠状态-S2.3 休眠状态-D2.4 暂停状态-T2.5 僵尸状态-Z僵尸进程的危害 2.6 死亡状态-X2.7 孤儿进程 1.进程状态
1.1 阻塞
阻塞#xff1a;进程因为等待某种条件就绪#xff0c;而导致的… 目录 1.进程状态1.1 阻塞1.2 挂起 2. 进程状态2.1 运行状态-R进一步理解运行状态 2.2 睡眠状态-S2.3 休眠状态-D2.4 暂停状态-T2.5 僵尸状态-Z僵尸进程的危害 2.6 死亡状态-X2.7 孤儿进程 1.进程状态
1.1 阻塞
阻塞进程因为等待某种条件就绪而导致的一种不推进的状态 通俗来说阻塞就是进程卡住了因为缺少了某种资源
所以阻塞一定是在等待某种资源
为什么阻塞
因为进程要通过等待的方式等具体的资源被别人用完之后再被自己使用。
简单理解进程等待和资源
资源比如磁盘、网卡、显卡 等各种外设例如当我们下载游戏时下载速度0kb此时CPU无法继续正常的下载需要等待网络资源CPU就将这个进程设置为阻塞状态此时进程就在等待。
具体理解进程等待
系统为了管理各种各样的进程需要为进程先描述创建task_struct然后再组织形成双链表形式的数据结构同样系统为了管理各种各样的硬件资源磁盘、网卡、显卡 等各种外设就需要为他们创建struct来对硬件资源进行描述然后再组织形成数据结构 例如为了管理网卡操作系统创建了struct dev其中包含了struct task_struct* queue的等待队列当一个进程等待网卡资源时cpu无法调度这个进程这个进程就被维护在网卡struct dev结构体中的queue等待队列中。 例如当scanf等待用户输入时该进程就是阻塞状态这个进程被维护在键盘struct dev结构体中的queue等待队列中。
实际操作系统的实现要复杂的多这只是一个基本的理解过程。
总的来说 阻塞就是进程不被调度一定是当前进程需要等待某种资源就绪一定是进程的 task_struct 结构体需要在某种被 OS 管理的资源下排队
1.2 挂起
挂起当 CPU 资源紧张时将 进程的代码和数据交换至磁盘中挂起此时内存中只有 PCB 挂起可以看作一种特殊的阻塞状态,因此挂起的全称是阻塞挂起
2. 进程状态
进程和程序不相同进程是活动的且有状态变化的。一个进程是有多个状态的。
这里我们具体谈一下Linux操作系统中的进程状态Linux操作系统的源代码当中对于进程状态有如下定义 static const char * const task_state_array[] { “R (running)”, /* 0 / “S (sleeping)”, / 1 / “D (disk sleep)”, / 2 / “T (stopped)”, / 4 / “t (tracing stop)”, / 8 / “X (dead)”, / 16 / “Z (zombie)”, / 32 */ task_struct是一个结构体内部会包含各种属性其中就有状态 struct task_struct { int status; … } 2.1 运行状态-R
进程是R状态不代表正在运行代表可被调度。换句话说进程只有是R状态才可被调度其他状态要先转为R状态才能被OS调度。
这表明处在运行状态的进程要么是在被OS调度中要么在运行队列里。 当操作系统需要切换进程运行时就直接在运行队列中选取进程运行。
进一步理解运行状态
当我们运行下面这个简单的死循环我们再来查看当前进程的状态
#includestdio.h
#includeunistd.hint main()
{while(1){printf(Hello\n);}return 0;
}我们发现该进程并不是处在运行状态上他的状态是S睡眠状态 表示当前进程在前台运行中并不是在运行状态这和我们的认知相矛盾。 原因在于
代码中存在printf这个函数需要去访问外设资源。我们知道CPU的速度非常快外设的速度非常慢。当printf想要访问屏幕外设来打印时这个外设并不一定准备就绪因此进程就在这个外设的等待队列中等待。外设准备就绪进程被CPU调度打印工作几乎一瞬间就运行完成因此这个状态R很难被查询到。绝大多数的时间进程都在外设等待队列中排队所以我们就查到S睡眠状态。
2.2 睡眠状态-S
睡眠 S 的本质就是 进程阻塞表示此时进程因等待某种资源而暂停运行。 睡眠 S也称作可中断睡眠我们可以强制将其关闭。
ctrl c 关闭 注意处在后台运行也就是不带号的的进程无法使用ctrl c来关闭。 kill命令关闭 kill -9 pid 2.3 休眠状态-D
当一个进程处于休眠状态disk sleep时表示该进程不会被杀掉即便是kill命令和操作系统也不行只有该进程自动唤醒才可以恢复。 休眠也称为 不可中断睡眠
2.4 暂停状态-T
我们可以让进程处于暂停状态
通过kill -l命令来查看信号 我们可以使用19.SIGSTOP和18.SIGCONT来使进程暂停和恢复
kill -19 PID 暂停进程kill -18 PID 恢复进程
暂停进程 恢复进程 注意在 gdb 中调试代码时打断点实际上就是使进程在指定行暂停运行此时进程处于追踪暂停状态 t
2.5 僵尸状态-Z
Linux当进程退出时一般进程不会立即退出而是会维持一个状态------僵尸状态Z 目的是为了方便后续父进程或是OS读取子进程的退出结果
创建一个父子进程并运行。 终止子进程就可以看到子进程的状态变成了僵尸进程
僵尸状态是必要的进程的退出状态必须被维持下去因为他要告诉关心它的进程父进程你交给我的任务我办的怎么样了。 而任务完成的结果可以用退出码来体现。
#includestdio.h
#includeunistd.hint main()
{while(1){printf(Hello\n);sleep(1);}return 0;
}这个返回值0返回给了操作系统告诉他任务顺利完成。 在Linux操作系统我们可以使用**echo $?**命令获取最近一次进程退出时的退出码。 echo $? 僵尸进程的危害
维护退出状态本身就是要用数据维护也属于进程基本信息所以保存在task_struct(PCB)中换句话说Z状态一直不退出PCB一直都要维护不能释放。 如果不能对僵尸进程进行回收就会造成内存泄漏的问题。
2.6 死亡状态-X
这个状态只是一个返回状态我们不会在任务列表里看到这个状态。因为当一个进程的退出信息被读取后该进程所申请的资源就会立即被释放该进程也就不存在了。
2.7 孤儿进程
当创建一个父子进程如果退出子进程此时子进程就成了僵尸进程。当先退出了父进程时此时的子进程就被称为孤儿进程 当退出父进程后父进程无法通过ps指令查询出来说明此时的父进程已经被回收了。此外子进程的PPID变成了1也就是操作系统。
父进程的父进程是bash有回收机制因此无法看到僵尸进程。当终止父进程时此时的子进程会被OS领养 被领养后后续子进程退出就能被回收了。这也就是OS领养的原因 以上就是我们对“进程状态”这一主题的全面探讨。通过此次学习我们初步掌握了进程的不同状态理解了何为阻塞状态及其产生的原因。同时我们也深入了解了进程状态转换的各种情况为今后更深入地学习和控制进程状态奠定了坚实的基础。