【Linux操作系统】Linux进程状态和两个特殊进程
文章目录
- 一.一套普适性的进程状态理论
- 1.运行
- 2.阻塞
- 3.挂起
- 二.一套具体的Linux进程状态
- 1.R-运行
- 2.S-睡眠
- 3.T-暂停
- 5.t-被追踪
- 三.僵尸进程和孤儿进程
- 1.僵尸进程
- 2.孤儿进程
一.一套普适性的进程状态理论
1.运行
由于CPU数量相对于进程数量来说少之又少,所以CPU维护了一个运行队列,方便管理大量等待CPU资源的进程.
同时由于CPU的处理速度很快,位于运行队列中的每一个进程都必须随时准备被运行, 所以只要位于运行队列中的进程都是处于运行状态.
值得注意的是处于运行状态的进程不一定是正在被CPU运行,但处于运行状态的进程一定是在CPU的运行队列中.
2.阻塞
我们知道磁盘等外设资源的读写速度相对于CPU相差甚远,所以当有些进程进程需要访问外设,比如数据打印到显示器,当CPU知道他们需要访问外设,CPU为了整体效率,肯定不能停下等,等待进程访问外设完后继续为其服务.
所以操作系统会把需要访问外设 (比如磁盘) 的进程从运行队列拿到内存中—磁盘所维护的等待队列中进行等待磁盘资源就绪.那么位于等待队列中的进程所处的状态就被称为阻塞状态.
值得注意的是:
实际上进程所处的状态取决于其所处的是何种队列
并非进程位于队列中,而是进程所对应的PCB位于队列中排队
进程所处的状态都在task_struct(PCB)中以数字含义的形式记录着
3.挂起
当大量要访问外设的进程, 都在等待外设资源就绪之时,他们是不会被立即调度, 未来可能还要等待很长的时间.
然而进程PCB和对应代码和数据都是要占用内存资源
所以操作系统就会自主地把一些等待外设资源就绪的进程所对应的代码和数据从内存换出到磁盘上,但是PCB仍然作为进程存在的标志,依旧保留在内存—-磁盘所维护的等待队列中
从而为内存节省了空间.
值得注意的是:
- 毕竟PCB依旧位于等待队列中, 所以挂起也是阻塞状态的一种
- 挂起是操作系统自主的行为,用户并不关心
二.一套具体的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 */
};
1.R-运行
写一段纯计算的代码:
1 #include<stdio.h> 2 #include<unistd.h>3 int main()4 {5 int a=0;6 while(1)7 {8 a++;9 }10 return 0;11 }
进程转态查看:R+
2.S-睡眠
写一段访问外设的代码/睡眠X秒的代码:
1 #include<stdio.h>2 #include<unistd.h>3 int main()4 {5 int a=0;6 while(1)7 {8 a++;//和上面代码区别在下面一行:打印到显示器9 printf("a:%d\n",a); 10 }11 return 0;12 }
进程转态查看:S+
3.T-暂停
首先介绍一下kill:
kill -l
9号信号:SIGKILL杀进程信号
19号信号:SIGSTOP暂停信号
18号信号:SIGCONT继续信号
接着演示两种如何出现暂停状态:
从R+ => T =>R:
从S+ => T =>S:
恢复成后台进程进程,ctrl+C无法终止:
状态S+和S的区别
S+状态的进程是前台进程, 在该状态下,CTRL+C可以终止进程,shell命令不可被正常执行.
S 状态的进程是后台进程, 在该状态下,CTRL+C不可以终止进程,shell命令可以被正常执行.
4.D-深度睡眠
</给大家讲个三个人的故事了解一下即可:
我们知道, 一般用户数据都永久保存在磁盘上,因为用户数据很重要,所以磁盘的地位也很重要! 有一天一个进程A抱着一堆数据来找磁盘,让磁盘保存.
磁盘
:你把用户重要数据
从内存拿过来,但是我保存需要时间,你得等一段时间哦!
进程A把用户数据交给磁盘,并在内存中苦等
…同时内存空间不够了
操作系统
:内存空间不够,我快顶不住了,进程挂起也解决不了问题,我得杀进程
来解决问题!
操作系统看到占着茅坑不拉屎的进程A,便在不知情的情况杀掉了进程A…同时磁盘保存数据失败,来向进程A反馈,但进程A已然死亡.
磁盘
:进程A,我保存数据失败了,用户数据还给你.
但内存中并无进程A的回应, 于是磁盘将数据丢掉,继续为其他进程服务…同时用户发现数据丢失,前来问责
.
磁盘
:我只是听话照做,数据本来就可能会保存失败,罪责与我无关.
进程A
: 我也是工具人,我办事情到一半就被干掉了,我还没找操作系统算账呐.
操作系统
:用户你给我的权力啊,内存压力大,挂起都不顶用,再说我杀掉进程A我也不是针对他,我不知道他拿着重要数据嘛.
用户听了三者都无罪,于是用户定了一个新规…
用户
:我给一些重要的进程一块免死金牌
,他特殊,你再怎么样也别杀他.
磁盘,进程A,操作系统都一致称好…
了解D深度睡眠状态:
深度睡眠状态一般在企业内部做高IO或者高并发用的多,处于深度睡眠状态的进程无法被操作系统杀死,只能通过断电重启或者进程自己醒来。
5.t-被追踪
我们在使用gdb调试代码的时候,进程会处于一种被追踪状态,等待开发人员查看上下文数据,这也就是为什么我们能够调试代码的原因。
ps:
- S和D,T和t其实都是阻塞状态的一种,这就是具体的一款操作系统和抽象的操作系统理论之间的差别
- X-死亡状态,死亡的进程直接被父进程回收,Linux下没法演示,但好理解。
- D-僵尸状态/将死状态,将于<三>大概了解,后进程控制深入理解
三.僵尸进程和孤儿进程
1.僵尸进程
僵尸进程:子进程退出,其代码和数据被回收,但是PCB中保存着退出码等退出信息,PCB没有被立即回收,得等待父进程读取退出信息完再彻底死亡,子进程就是僵尸进程.
僵尸:Zombie
已故的:defunct
Linux下查看僵尸进程:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h> 4 int main()5 {6 pid_t pid=fork();7 if(pid<0)8 {9 perror("Error\n");10 return 0;11 }12 else if(pid==0)13 {14 printf("I am child,PID:%d,PPID:%d\n",getpid(),getppid());15 sleep(5);16 exit(1);17 }18 else 19 {20 while(1) 21 {22 23 printf("I am parent,PID:%d,PPID:%d\n",getpid(),getppid());24 sleep(1);25 }26 }27 return 0;28 }
僵尸进程的危害:
- 子进程退出,子进程的状态就会变成僵尸状态,如果父进程一直不回收子进程占用的资源,那么PCB就要一直被维护.
- 如果父进程创建了很多这样的子进程,那么就会造成内存泄漏的问题.
2.孤儿进程
但是如果父进程先于子进程退出,子进程退出时,谁来完成子进程的退出信息读取和资源回收呐?
孤儿进程: 父进程退出, 子进程被操作系统领养,操作系统完成子进程退出信息读取和资源回收,子进程就是孤儿进程.
Linux下查看孤儿进程:
1 #include<stdio.h>2 #include<unistd.h>3 #include<stdlib.h> 4 int main()5 {6 pid_t pid=fork();7 if(pid<0)8 {9 perror("Error\n");10 return 0;11 }12 else if(pid==0)13 {14 while(1)15 {16 printf("I am child,PID:%d,PPID:%d\n",getpid(),getppid());17 sleep(1); 18 }19 }20 else21 {22 printf("I am parent,PID:%d,PPID:%d\n",getpid(),getppid());23 sleep(5);24 exit(1);25 }26 return 0;27 }
父进程退出,父进程的退出信息读取和资源回收工作由bash完成
因为子进程退出的时候也有退出信息读取和资源回收工作,所以要被领养
事实证明,子进程被操作系统领养,变成S状态,前台进程变成后台进程。
【Linux操作系统】Linux进程状态和两个特殊进程相关推荐
- 怎么安装redhat linux操作系统,Linux操作系统RedHat6.5安装
1.说明 安装Linux操作系统Red Hat 6.5, 安装镜像为rhel-server-6.5-x86_64-dvd.iso. 2.开始安装 在BIOS里设置成从光驱启动, 服务器上电后会加载光驱 ...
- 怎么自学linux操作系统,linux操作系统好学吗_要学什么
描述 linux操作系统的基础知识是比较好学的,但是需要我们通过大量地练习来牢记这些基础知识. Linux操作系统依靠其多用户和多任务.跨平台硬件支持.丰富的软件支持.可靠的安全性.良好的稳定性和完善 ...
- 梅花linux操作系统,Linux操作系统 精伦H3多媒体中心促销
英特尔处理器,DDR内存,Linux操作系统,这些只会出现在电脑上的名词全都出现在了笔者今天要给大家介绍的这款精伦H3高清播放机上,他颠覆了高清播放机的概念,使得机器既有了高清播放机便携小巧省电的特点 ...
- geany设置运行linux,[操作系统]linux强大IDE——Geany配置说明
[操作系统]linux强大IDE--Geany配置说明 0 2015-04-04 18:01:04 今天开始用Ubuntu了(主要是为了防止自己在windows下不自觉的打游戏之类的) 刚开始用的 ...
- Linux操作系统~什么是虚拟地址?深度剖析进程地址空间
目录 1.所以进程的地址空间是什么呢? 2.mm_struct内部有什么? 3.虚拟地址空间与物理内存如何关联 页表 4.为什么设计这样一个进程地址空间,不让程序直接访问内存 Q:为什么子进程修改值以 ...
- Linux操作系统——Linux可视化管理-webmin 和 bt 运维工具
文章目录 25 Linux 可视化管理-webmin 和 bt 运维工具 25.1 webmin 25.1.1 基本介绍 25.1.2 安装webmin&配置 25.1.3 简单使用演示 25 ...
- 《Linux操作系统 - 驱动开发》第9章 进程上下文、中断上下文及原子上下文
谈论进程上下文 .中断上下文.原子上下文之前,有必要讨论下两个概念: a – 上下文 上下文是从英文context翻译过来,指的是一种环境.相对于进程而言,就是进程执行时的环境: 具体来说就是各个变量 ...
- linux操作系统之信号量、互斥量在进程间的同步、文件锁
(1)信号量:进化版的互斥量 多个线程间对某个对象的部分数据进行共享,使用互斥锁是没有办法实现的,只能将整个数据对象锁住.这样虽然达到了多线程操作数据共享的目的,却导致线程并发性下降. 信号量:相对折 ...
- [入门篇]Linux操作系统fork子进程的创建以及进程的状态 超超超详解!!!我不允许有人错过!!!
目录 0.前言 1.fork()创建子进程讲解 1.1fork()的简单介绍 1.2 创建子进程详解 1.2.1 如何理解fork创建子进程 1.2.2 子进程的PCB以及子进程的代码和数据 1.2. ...
最新文章
- java hashmap 转对象_Java – 从HashMap中获取正确的转换对象
- php中函数的定义格式,在php中函数定义的格式
- 【Python】反转列表 list 的几种方法
- 目标检测的“尽头”竟是语言建模?Hinton团队提出Pix2Seq:性能优于DETR
- Hbase总结(八)Hbase中的Coprocessor
- JVM(4)——对象访问
- JavaScript RegExp(正则表达式) 对象
- iBATIS date MySQL_LocalDateTime与mysql日期类型的交互(基于mybatis)
- It was in 2006, and as a desktop computer
- Request库入门
- php页面开发,PHP网站开发中常用的8个小技巧
- html文件用的那个版本,html – 使用Django进行静态文件版本控制
- Matplotlib Toolkits:地图绘制工具
- what is a rx ring/tx ring in router?
- c语言嵌入式开发键盘,C语言嵌入式系统编程修炼之键盘操作篇
- Oracle存储过程实现X日均线计算
- 一文彻底搞懂python面向对象编程(全网最全!!!)
- C# 读取txt文件生成Word文档
- hexo搭建github.io博客
- 第一次作业:读博文有感
热门文章
- WannaCry勒索病毒分析过程**上**
- jconsole连接远程服务
- 启动SpringBoot报错:Field userService in com.sunshin.controller.UserController required a bean of type...
- Python从小白到新手
- Pyecharts坑之一---“画图不显示“
- 航空摄影测量中yaw,pitch,roll
- windows下的python安装scrapy
- B 站硬件大佬又在 GitHub 上开源了一款神器...
- IOS欢迎界面Launch Screen动态加载广告
- 二极管反向恢复时间和反向恢复电流