进程的一生(一)

进程的简要介绍

所谓进程就是资源分配的单位,所以呢要搞清楚一个进程就要搞清楚它的资源,在linux里面的进程控制块PCB就是一个task_struct结构体,可以猜想这个结构体肯定要包含各种资源管理的单位,比如mm指针就指向该进程内存的描述,即struct mm_struct用来管理进程的内存资源,fs指针描述文件系统资源,比如该进程运行时候的权限,路径…,这也是一个进程关心的,所以也属于进程管理的资源,files指针描述文件资源,比如该进程打开了哪些文件…该指针指向一个struct files_struct结构体,该结构里面的fd_array用来存放打开文件的fd(文件句柄),这显然也是进程管理的资源,除此之外还有其他的一些的资源管理.
进程的一生(一)_第1张图片
我们可以通过cat /proc/sys/kernal/pid_max来查看系统内最多的进程数,可以看出系统内的进程数是有限的
在这里插入图片描述
刚才我们提到task_struct是描述进程的数据结构,那linux内核中是如何组织这些结构体的呢,因为进程中存在父子进程的概念,显然我们使用链表来组织这些结构是行不通,答案很明显linux内核是通过树结构来管理进程结构体的,可以通过pstree命令来查看该进程树的结构,在linux内核还存在哈希数据结构,比如我们通过命令kill - 2 6666就能释放pid号为6666的进程的资源,通过pid号找到task_struct结构就是哈希数据结构,当然你只是想遍历所有进程,用链表也是可以的.

进程的生命周期

进程的一生(一)_第2张图片
我们先来看下面的三个方框,在linux里一个进程被fork()后就处于就绪态,当时间到来的时候就变成运行态运行,当时间片用完或者被优先级更高的进程被抢占了又返回了就绪态,时间片的存在是为了并发运行,称为分时调度,当我们在运行态的时候我们需要等待资源,但是我们不能死等,这无疑是对资源的一种浪费,比如等待网络串口数据,等网络发包,所以等待资源时我们需要切换成睡眠态,让出CPU资源,当等到了资源就又切换到就绪态,为什么一醒来就是就绪态而不是运行态,因为醒来的时候需要任务调用,醒来的任务不一定优先级是最高,只有你拼得过别人才能被运行,我们这里只有三个框就看似完成了操作系统的任务调度了呀,为什么linux需要六个框呢?下面讲解
进程的一生(一)_第3张图片僵尸态(TASK_ZOMBIE)
在linux里面任何一个进程死了以后,它都会变成一个僵尸进程,所谓僵尸进程就是进程本身依附资源空间已经消失,但是task_struct还没有消失,它只能让它的父进程通过wait4的API去等待它死,该僵尸进程才会消失,即使使用"kill -9 pid"也杀不死(都是僵尸了,再怎么捅刀子也是死僵尸),说僵尸进程是一个非常短的临界状态,就是一个进程死了,父进程没来得及wait4的情况就是僵尸,那么为什么僵尸进程的task_struct不会消失呢?这是父进程中可以通过该结构体查到子进程死因,用户可以通过wait_pid()函数来指定子进结束,其函数定义在/usr/include/sys/Wait.h文件中,函数声明如下

extern __pid_t waitpid(__pid_t __pid,int *__stat_loc,int __options)
第一个参数为进程的PID值
PID>0 表示等待进程PID为PID值的进程结束
PID==-1 表示等待任意子进程结束,相当于调用wait函数
PID==0 表示等待与当前进程的进程组PGID一致的进程结束
第二个参数为调用它的函数中某个变量地址,如果执行成功,则用来存储结束进程的结束状态
第三个参数为等待选项,可以设置为0,也可以设置为WNOHANG和WUNTRACED,WNOHANG表示不阻塞等待,WUNTRACED表示报告状态信息

停止态(TASK_STOPPED)
所谓停止态就是让当前进程停止下来让出CPU,用cltr+z可以让进行停止,用fg命令又可以让停止的进程继续,比如生活中我们在安装游戏的时候,突然女朋友一个电话,我们就得暂停当前的游戏安装状态去接女朋友电话,当打完电话后我们就可以继续安装游戏了,它就会接着继续安装下去,不会把接电话的安装进度给废除掉了,除此之外,还可以使用cpulimit命令来控制,cpulimit -l 50 -p 1212,限制pid为1212程序的cpu使用率不超过10%

深睡眠和浅睡眠
深睡眠就是一定要等到资源来我才醒,比如串口没有收到数据我就是不醒,浅睡眠除了被资源唤醒,还可以被信号唤醒,即深睡眠用户层是无法唤醒的,一切的进入都是在内核层,

如下图,进程的生命周期就一目了然了
进程的一生(一)_第4张图片

你可能感兴趣的:(进程的一生(一))