目录
- 一、什么是进程
- 二、进程状态
- 1、Linux下的进程状态
- 2、两个特殊进程
- 1、僵尸进程
- 2、孤儿进程
- 三、进程优先级
一、什么是进程
进程就是程序的一个执行实例,也就是正在执行的程序,然后由操作系统帮助我们将程序转化为进程,完成特定的任务。
进程 = 内核关于进程的相关数据结构 + 当前进程的代码和数据
那么操作系统又是怎样管理进程的呢?
我们对应的进程是需要被操作系统管理的,而管理的思路是先描述,再组织,为了更好的描述进程,所以每一个操作系统把可执行程序加载进内存都会创建一个对应的数据结构对象。这个对象称为PCB,他是所有进程属性的集合,操作系统直接对PCB进行管理。在Linux中描述PCB的结构体称为task struct。
二、进程状态
运行状态: 进程在运行队列里,就是运行状态,并不是进程在运行当中,就是运行状态。
阻塞状态: 进程因为等待某种条件就绪,从而导致进程不被调度,也就是我们常说的程序卡住了。简而言之,进程等待某种外设资源就绪的过程,就是阻塞状态。
挂起状态: 如果系统中存在一个下载任务的进程,而此时没有网卡设备,进程就进入阻塞状态。当存在许多进程时,系统正在调度其他程序,并且系统中内存资源紧张时,系统就会把那些不被调度的进程相关的代码和数据交换到磁盘当中,此时,内存中这部分的代码和数据就可以被释放了。把进程相关的代码和数据交换到磁盘中去,这时候进程就处于挂起状态。
1、Linux下的进程状态
- R:运行状态,并不意味着进程一定在运行中,它表明进程要么在运行中,要么是在运行队列里。
- S:睡眠状态,是一种阻塞状态,意味着进程在等待事件完成
- D:休眠状态,是一种阻塞状态,也可叫不可中断休眠状态,在这个状态的进程通常会等待IO的结束
- T:暂停状态,是一种阻塞状态,可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
- X:死亡状态,是一种终止状态,这个状态只是一个返回状态,不会在任务列表里看到这个状态
- Z:僵尸状态,也是一种终止状态。
我们可以举个例子来查看R的状态:
我们先创建一个test.c 的文件,进行编写:
然后对这个代码运行,通过 ps axj | head -n1 && ps ajx | grep test | grep -v grep
指令查看进程状态
我们可以看到并不是处于R状态,我们把代码在改一改呢?
此时,进程状态就处于R状态,为什么呢?
因为printf的本质是向外设打印消息,而频繁访问外设,是需要等待的,对于CPU来说,外设速度是非常慢的,而运行就是一瞬间的事情,所以我们一直看到的就是S状态。当注释掉printf时,此时代码中没有任何访问外设资源的代码,只有while循环判断,一直处于计算,所以他在整个调度周期里,只会用CPU里的资源,所以一直处于R状态。
我们可以举个例子来查看T的状态:
此时,这串代码正在处于运行状态:
我们使用kill -19 22337
指令,使他进入暂停状态。
我们还可以使用kill -18 22337
指令,使他继续运行
综上所述,我们会看到有的是S+,有的是S状态,为什么呢?
有加号,则是在前端运行,而没有加号,则是在后端运行,而且在后端运行,使用Ctrl + C 杀不掉程序,可以用kill -9 PID 命令杀死程序。
2、两个特殊进程
1、僵尸进程
僵死状态是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。
Linux当进程退出的时候,一般进程不会立刻退出,而是维持一个叫Z的状态,也就是僵尸状态,方便后续父进程读取孩子进程退出的退出结果。
僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。直到读取到退出状态代码,进程就会进入X状态。
我们举个例子,查看僵尸状态:
让子进程退出,父进程正常运行,但是父进程一直不回收
进入运行,我们可以看到父子进程正在运行
如果我们把子进程杀死呢?
我们可以看到子进程就进入Z状态了。
僵尸进程的危害:
- 进程的退出状态是一直要维持下去的,因为他要告诉父进程,你交给我的任务,我办的怎么样。如果父进程一直不读取,那么子进程就会一直处于僵尸状态
- 维护退出状态本身就要用数据维护,也就是说退出状态也属于进程的基本信息,所以Z状态一直不退出,PCB就会一直都要被维护。
- 如果一个父进程创建多个子进程,而一直不回收,就会造成内存资源的浪费,因为数据结构对象本身就要占用内存,就会出现内存泄漏的问题。
2、孤儿进程
父子进程中,父进程先退出,而子进程暂时没有退出,就会被1号进程自动领养,也就是让1号进程成为新的父进程,而1号进程就是操作系统,这就是 孤儿进程。
我们写个代码看看孤儿进程:
我们可以看到杀死父进程后,子进程会由前端自动变为后端。此时,我们可以用两种方式杀掉进程:
1、kill -9 PID
2、killall 程序名称
三、进程优先级
进程优先级存在的意义就是CPU资源有限。
- CPU资源分配的先后顺序,就是指进程的优先权。
- 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的Linux很有用,可以改善系统性能。
- 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
查看系统进程
在linux系统中,用ps –l
命令则会类似输出以下几个内容:
- UID : 代表执行者的身份
- PID : 代表这个进程的代号
- PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
- PRI :代表这个进程可被执行的优先级,其值越小越早被执行
- NI :代表这个进程的nice值
PRI and NI
- PRI就是进程的优先级,或者说就是程序被CPU执行的先后顺序,此值越小进程的优先级别就越高。
- NI就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
- PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice。当nice值为负值的时候,那么PRI(new)值将变小,即其优先级会变高,则其越快被执行。所以,调整进程优先级,在Linux下,就是调整进程nice值
- nice其取值范围是-20至19,一共40个级别
- nice值就是进程优先级的修正修正数据
如何更改与存在进程的nice值呢?
先输入top,进入top后,按‘r’,然后输入进程PID,输入nice值。
进程特性:
- 竞争性:系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。
- 独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰。
- 并行:多个进程在多个CPU下分别同时进行运行,这称之为并行。
- 并发:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。