Linux 进程(一) 进程概念和进程状态(僵尸进程、孤儿进程、守护进程)
- 进程的概念
- 进程状态
- 僵尸进程、孤儿进程、守护进程
进程的概念
程序:一系列有序的指令集合(就是我们写的代码)
进程:进程就是程序的一次执行,是系统进行资源分配和调度的独立单位。
程序是一个没有生命的实体,只有操作系统执行它时,它才能成为一个活动的实体,也就是进程。同时,操作系统通过进程控制块(PCB),来对程序进行调度使用
操作系统如何控制和调度程序
按照冯诺依曼体系结构,所有的数据想要被CPU进行处理,第一步就是要将代码和数据加载到内存中。
由于早期CPU的性能不足,无法同时调度所有文件,所以CPU使用了一种解决方法,也就是CPU分时机制。
CPU分时机制:通过极快的速度切换和调度运行所有的程序,造成了同时运行的假象。
但是,这里还存在着几个问题,CPU是如何在内存中找到每个程序的?CPU在来回调度时,如何能够从上一次运行的位置继续运行?如何能够保证继续处理上一条没有处理完的数据?
所以操作系统为了能够完成这些操作,设置了一个用于描述进程信息的数据结构,也就是我们通常所说的PCB。
进程控制块–PCB
操作系统为了能够使每个程序能够独立运行,在操作系统中为其配置了一个数据结构,也就是我们通常所说的PCB(Process Control Block),这个数据结构在Linux下是:task_struct
task_struct中的内容
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。 其他信息
PCB是操作系统对一个运行中的程序(也就是进程)的描述,操作系统通过这个描述来实现对程序的运行调度
操作系统正是通过一个一个的PCB来对运行中的程序进行调度使用。
回到前面提出的问题,CPU通过PCB中的内存指针来找到程序在内存中的地址,通过上下文数据来记录运行中程序的各种信息,通过程序计数器来找到这个程序即将执行的下一条指令的地址。
子进程
当我们在一个已经创建的进程内通过fork创建一个新的进程时,这个新的进程就是原先进程的子进程。
在子进程创建的时候,它从父进程的PCB中复制了很多数据,如内存指针、上下文数据、程序计数器等,所以它的代码、数据以及运行的位置,都与父进程一模一样。
由于代码段是只读的,所以两者的代码都一样,不可修改,而两者虽然虚拟地址相同,但物理地址不同,所以两者的数据都各自独立。
总结一下就是:父子进程代码共享,数据各自开辟空间。(利用写时拷贝技术)
在Linux中,我们可以通过fork函数来创建子进程
pid_t fork(void)
我们创建子进程,是希望它和父进程执行不一样的操作,那么我们该怎么实现呢?
最简单的方法就是通过fork的返回值来进行代码分流,父进程的返回值是子进程的pid,而子进程的返回值是0,通过对返回值的判断,即可完成代码的分流。
但是这种方法的代码十分冗余,还有一种更加优秀的方法------程序替换(后几篇会写)
僵尸进程、孤儿进程、守护进程
在我们学习操作系统的时候,里面提到进程有三种基本状态,就绪、阻塞、终止。
但是在linux中,将状态细分到了六种。
- R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
- S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
- D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
- T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
- X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态
- Z僵死状态(Zombies) :进程已经退出了但是资源还没有完全被释放的一种状态。
进程的概念
僵尸进程
这里的有一种特殊的状态值得一提,就是僵死状态
当子进程退出的时候,如果父进程没有读取到子进程的返回值,这时就进入了僵死状态。
这时就处于一个很尴尬的局面,子进程实际上已经退出了,但是父进程认为它还在执行,所以并没有释放它的资源,所以子进程会一直卡在进程表中,等待父进程读取退出状态代码。
下面是在Linux下的实验
此时两者都处于休眠状态
13284是父进程, 13285是子进程。
这时如果我们使用kill将子进程杀死
这时,子进程就变为了僵尸进程。
因为它被强制结束,没有给父进程返回退出的状态值,所以资源一直无法释放,我们也无法再将其杀死
即使是kill -9对其也没有作用
这时只有两种解决方法
1. 进程等待
2. 退出父进程
进程等待较为复杂,后面几篇会讲。
所以我们试试退出父进程
父进程退出,子进程保存退出的状态就没有任何意义了,因此就被释放了
这时,僵尸进程就解决了,但是这并不是一个合理的方式,我们不能通过这种方法来解决问题,所以应该避免僵尸进程的产生。
从上面可以看出,僵尸进程是非常危险的,因为我们无法通过正常途径将其解决,同时它会一直占用着我们的资源,同时PCB还需要对它的状态进行维护。并且一个用户所能创建的进程数量是有限的,如果一个父进程创建了大量的子进程而不进行回收,当达到上限时,我们就无法创建新的程序。
孤儿进程
如果父进程先于子进程退出,那么没有父进程的子进程会怎么样呢?
会没有没有人回收,就像僵尸进程一样一直占用资源?
实验一下
杀死父进程14760
我们会发现,失去了父进程后的子进程并不是没有父进程,而是会被1号进程init统一收养,然后由Init进程回收
- 父进程先退出,子进程就称之为“孤儿进程”
- 孤儿进程统一被1号init进程收养,由init进程进行回收
守护进程(精灵进程)
守护进程:一种特殊的孤儿进程,父进程是一号进程,运行在后台,与终端和登陆会话脱离关系,不受影响。
守护进程通常是一种运行在系统后台的批处理程序,默默的做一些循环往复的事情
这些TPGID为-1的都是守护进程
Linux 进程(一) 进程概念和进程状态(僵尸进程、孤儿进程、守护进程)相关推荐
- 守护进程中创建的对象php,在PHP中生成守护进程(Daemon Process)
前两天看到一篇文章<如何使用PHP编写daemon process>,其中对核心代码却没有细说,我又查了一些资料,还看了一本<理解Unix进程>,才搞明白生成守护进程的时候发生 ...
- Linux系统编程之--守护进程的创建和详解【转】
本文转载自:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终 ...
- 浅析三种特殊进程:孤儿进程,僵尸进程和守护进程
其实有时想想linux内核的设计也蕴含着很多人生哲学,在linux中有这么几个特殊进程中,我们一开始见到它们的名字可能还会觉得很诧异,但在了解完了原理后,我们仔细想想,这样的命名也不无道理!下面我就给 ...
- 浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.
其实有时想想linux内核的设计也蕴含着很多人生哲学,在linux中有这么几个特殊进程中,我们一开始见到它们的名字可能还会觉得很诧异,但在了解完了原理后,我们仔细想想,这样的命名也不无道理!下面我就给 ...
- linux系统编程之进程(八):守护进程详解及创建,daemon()使用
linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等 ...
- 僵尸进程孤儿进程与守护进程
其实有时想想linux内核的设计也蕴含着很多人生哲学,在linux中有这么几个特殊进程中,我们一开始见到它们的名字可能还会觉得很诧异,但在了解完了原理后,我们仔细想想,这样的命名也不无道理!下面我就给 ...
- 浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程
昨天学了进程控制,就这三种特殊的进程研究了一下,其中也借鉴了一些前人总计的经验. 1.孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这里子进程的父进程就是init进程( ...
- Linux 守护进程创建原理及简易方法
1:什么是Linux下的守护进程 Linux daemon是运行于后台常驻内存的一种特殊进程,周期性的执行或者等待trigger执行某个任务,与用户交互断开,独立于控制终端.一个守护进程的父进程是in ...
- Linux进程学习(孤儿进程和守护进程)
孤儿进程和守护进程 通过前面的学习我们了解了如何通过fork()函数和vfork()函数来创建一个进程.现在 我们继续深入来学习两个特殊的进程:孤儿进程和守护进程 一.孤儿进程 1.什么是 孤儿进程 ...
- 用c语言编写linux守护进程
2019独角兽企业重金招聘Python工程师标准>>> 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程 ...
最新文章
- Chemistry.AI | 基于图卷积神经网络(GCN)预测分子性质
- OpenYurt 深度解读:如何构建 Kubernetes 原生云边高效协同网络?
- 【C++】类型转换简述:四种类型转换方式的说明及应用
- 关于 HTTP 和 TCP 的 keep-alive
- c# 整数类型转byte_C#中数据类型的整数类型
- SQL手工注入入门级笔记(更新中)
- [深度学习-实践]GAN基于手写体Mnist数据集生成新图片
- 以太坊上DeFi协议总锁仓量首次突破350亿美元
- 【算法】2 由股票收益问题再看分治算法和递归式
- 大疆新品:机甲大师RoboMaster S1介绍(AI 学习小伙伴)
- 云时代的“双态IT”运维思路
- 解决天正M_批打印没有天正的打印格式(TArch20V6.ctb)的问题
- PAT甲级准备方法(附2021年PAT甲级秋季考试题解)
- 基因组组装---基因组大小评估(genome survey)
- 离散型随机变量的概率分布
- Django 实现单点登录(SSO)
- 细说汽车电子通信总线之CAN 2.0 总线协议详解
- ViewPager2和Fragment的组合使用
- firefox 邮件提醒
- layui中layer的使用
热门文章
- Nginx教程-日志配置
- linux+tomcat+apache
- VS2010+WinXP+MFC程序 无法定位程序输入点于动态链接库
- ubuntu编译qemu报错:‘ERROR: DTC (libfdt) version = 1.4.0 not present.’
- Rafy 框架-发布网页版用户手册
- zabbix配置发送报警邮件
- nginx平滑升级添加ssl实现站内https
- onRetainNonConfigurationInstance和getLastNonConfigurationInstance
- MyBatis第四天
- 结构体之位域全面分析