✨个人主页: Yohifo
所属专栏: Linux学习之旅
每篇一句: 图片来源
操作环境: CentOS 7.6 阿里云远程服务器
Perseverance is not a long race; it is many short races one after another.
- 毅力不是一场漫长的比赛;是许多短跑一个接一个。
进程
只有被OS管理好了,才能发挥它的全部功效,而系统中存在多个 进程
,OS无法做到面面俱到,因此为了更好的管理进程
,OS把 进程
分成了几种状态:阻塞、挂起、运行、休眠等等,至于每种状态的应用场景是什么、有什么用?本文将会带着大家认识的各种 进程
状态
在谈 进程状态
之前,首先要回顾下之前的 进程
相关知识
进程
,而是管理 进程
的 PCB(task_struct)
PCB
中有着进程的各种信息,包括:PID
、PPID
、进程状态
等getpid()
获取当前进程的 PID
进程
间存在父子关系,可以通过 fork()
主动创建 子进程
父子进程
相互独立,共享一份代码时,具有 写时拷贝
机制何为阻塞?
阻塞
就是 进程
因等待某种条件就绪,而导致的一种不推进状态阻塞
就是 进程
卡住了,原因就是缺少资源比如在我们日常生活中,常常发生堵车,原因就是道路资源不够用了,车辆这个 进程
就需要原地等待
那么进程
需要什么资源呢?
磁盘
、网卡
、显卡
等各种外设steam
上下载游戏,当你点击下载按钮后提示磁盘空间不足,此时是无法运行 steam下载
这个进程的,因为此 进程
需要等待足够大的 磁盘资源
进程
为 阻塞
状态原因
理解 进程阻塞
后,理解 进程挂起
就比较轻松了
挂起(阻塞挂起)
CPU
资源紧张时,将 进程
交换至 磁盘
中挂起,此时内存中只有 PCB
挂起可以看作一种特殊的阻塞状态
比如在我们生活中,一边走路一边玩手机很危险,所以此时我们会将玩手机这个 进程挂起
,即把手机揣进兜里,然后 专心执行走路这个 进程
进程
有各种运行状态,方便OS进行管理,在 Windows
中,进程
状态是这样的
而在我们 Linux
中,新建
、就绪
、运行
都可以看作 运行 R
这一个状态,所以比较清晰
进程是何种状态,取决于此进程的PCB在哪里排队
首先来看看第一种状态 R
以我们以往的认知来说,一个程序在运行就表示该 进程
处于 运行
状态,那么事实真的如此吗?
先来看看下面这段代码:
#include
using namespace std;
#include
#include
int main()
{
while(1)
{
cout << "I'm a process, my PID is:" << getpid() << endl;
sleep(1);
}
return 0;
}
当前 Makefile
文件为
myProcess:test.cpp
g++ -o myProcess test.cpp
.PHONY:catPI
catPI:
ps ajx | head -1 && ps ajx | grep myProcess | grep -v grep
.PHONY:clean
clean:
rm -r myProcess
通过 make catPI
指令调用 Makefile
中提前设定好的指令,查看当前进程信息
可以看到当前的进程状态为 睡眠 S+
注: +
表示当前进程在前台运行中
进程
难道没有运行吗?
很难捕捉到
进程
都在外设等待队列中 排队
进程
不用在等待队列中 排队
, CPU 就一直在处理死循环,此时可以观察到 运行 R
状态注意: R
表示此时 进程
已经在 运行队列
中排队了,但 进程
不一定在 CPU 上运行
睡眠 S
的本质就是 进程阻塞
,表示此时进程因等待某种资源而暂停运行;睡眠 S
又称为可中断休眠,当 进程
等待时间过长时,我们可以手动将其关闭,应用卡死后强制关闭也是这个道理
还存在一种特殊睡眠状态 休眠 D
,休眠
又被称为不可中断休眠,顾名思义,休眠 D
状态下的 进程
是无法终止的,kill
指令和 OS都无能为力,只能默默等待 进程阻塞
结束,拿到资源了,进程
才会停止 休眠 D
状态
终止 休眠 D
进程的一个方法就是切断电源,此时进程是结束了,但整个系统也结束了
倘若存在 休眠 D 进程长时间运行,那么此时就表示系统离宕机不远了
不可休眠状态比较少见,一般出现于IO阻塞
用途:
进程
,预防误杀现象我们还可以使 进程
进入 暂停 T
状态
kill -19 PID
暂停进程kill -18 PID
恢复进程
我们可以通过 kill -18 PID
使 进程
恢复运行,恢复后的 进程
在后台运行
注意: 进程
在后台运行时,是无法通过 ctrl+c
指令终止的,只能通过 kill -9 PID
终止
在 gdb
中调试代码时,打断点实际上就是 使 进程
在指定行暂停运行,此时 进程
处于 追踪暂停状态 t
当进程被终止后,就处于 死亡 X
状态
死亡状态是无法在任务列表中观察到的,死亡 X
状态只是一个返回状态
与死亡状态相对应的还有一个 僵尸 T
状态
僵尸状态
是给 父进程
准备的子进程
被终止后,会先维持一个 僵尸
状态,方便 父进程
来读取到 子进程
的退出结果,然后再将 子进程
回收bash
环境下终止 子进程
,是观察不到 僵尸状态
的,因为 bash
会执行回收机制,将 僵尸
回收fork()
函数自己创建 父子进程
关系,观察到这一现象#include
using namespace std;
#include
#include
int main()
{
pid_t ret = fork();
if(ret == 0)
{
while(1)
{
cout << "I'm son process, my PID: " << getpid() << " PPID: " << getppid() << endl;
sleep(1);
}
}
else if(ret > 0)
{
while(1)
{
cout << "I'm father process, my PID: " << getpid() << " PPID: " << getppid() << endl;
sleep(1);
}
}
else
{
while(1)
{
cout << "Make son process fail!" << endl;
sleep(1);
}
}
return 0;
}
此时输入指令 kill -9 PID
即 kill -9 28315
终止 子进程
再次查看进程状态:
僵尸进程如果不被回收,会导致内存泄漏问题和标识符占用问题
关于 僵尸进程
的更多信息,将会在下篇文章中介绍
孤儿进程是一种特殊的进程状态
父子进程
父进程
,此时 子进程
会被OS领养子进程
的 父进程
变为 1号进程
子进程
就变成了一个 孤儿进程
子进程
退出时就会无人回收,成为一只游离的僵尸僵尸进程
有 内存泄漏
的风险子进程
会被OS领养以上就是关于进程学习【二】的全部内容了,我们简单学习了 进程
的相关状态,知道了何为 阻塞
、进程
为什么 阻塞
的缘由,同时还见识了 进程
的各种状态,为以后 进程
进一步学习和控制打下了基础
如果你觉得本文写的还不错的话,期待留下一个小小的赞,你的支持是我分享的最大动力!
如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正
…
相关文章推荐
Linux进程学习【一】
Linux工具学习之【gdb】
Linux工具学习之【git】
Linux工具学习之【gcc/g++】
Linux工具学习之【vim】
Linux 权限理解和学习