进程
什么是操作系统
1.操作系统是一款软件,对上提供稳定的运行环境,对下进行软硬件管理工作
操作系统如何实现对进程的管理?
1、进程=内核数据结构+代码数据
2、在操作系统一书中内核数据结构被称为PCB,Linux环境下被称为task_struct,该数据结构中包含了进程的所以属性以及指向下一个进程的指针。
struct task_struct{
属性1...;
属性2...;
struct task_struct* next;
}
3、通过next指针将一个一个进程连接起来,对进程的管理就变成了对链表的增删改查,当有新的进程添加进来可以使用尾插的方式将进程插入到链表中。
4、总结:对进程的管理可以总结为——先描述,再组织,先描述即将进程描述为一个数据结构,再组织即通过指针将所有进程组织起。
进程中的部分属性(task_struct中的属性)
1.查看进程
pa ajx
2.进程id——PID
(1)每个进程都有自己唯一的标识符,即pid
(2)获取进程pid
#include<sys/types.h>
pid_t pid = getpid();
3.父进程id——PPID
(1)每个进程都会有自己的父进程,从命令行执行的程序的父进程是bash,bash的pid为1。
(2)获取父进程PID
#include<sys.types.h>
pid_t ppid = getppid();
4.前台进程与后台进程
(1)前台进程:带+即为前台进程,可被ctrl+c中断
(2)后台进程:不带+即为后台进程,只能被kill -9 pid指令中断
(2)启动程序时,后面带&可转为后台进程
./xxxxxx &
5.进程状态
(1)运行状态:进程在运行状态或在运行队列中,标识符为R
(2)阻塞状态
【1】睡眠状态:被称为可中断睡眠或浅度睡眠;进程在等待事件完成时会处于该状态,或主动调用sleep函数进入睡眠状态,标识符为S
【2】磁盘休眠状态:被称为不可中断睡眠或深度睡眠,不能被杀死;进程向磁盘写入后等待磁盘反馈时会处于该状态,标识符为D
【3】停止状态:可以通过kill -19 pid进入该状态,进入该状态的进程会转为后台进程,并且唤醒后仍然是后台进程,标识符为T
(3)僵尸状态:当进程执行结束等待父进程获取其进程退出信息时会处于该状态,标识符为Z
(4)孤儿进程:当父进程比子进程先结束,子进程的父进程会变为1号进程即bash,并转为后台进程
(5)挂起:当系统资源吃紧时,会将进程的代码数据唤出到swap分区,只保留PCB(task_struct),当轮到该进程执行时,再从swap分区中将代码数据唤入。
6.优先级——PRI与NI
(1)什么是进程优先级:进程优先级决定了进程获取资源的顺序,优先级的值越小,优先级越高
(2)NI:NI表示nice值,在Linux系统中修改优先级并不是直接对PRI进行修改,PRI固定为80,每次修改都是对nice值进行修改,nice值的范围为[-20,19],所以PRI的范围为[80-20,80+19],即[60,99]
(3)调整优先级的方法
输入top
输入r
(4)如果优先级设置的过低,长时间轮不到该进程执行,无法满足该进程执行所需的时间,会引发进程饥饿
父子进程
1.为什么要创建子进程:为了让父子进程执行不同的代码
2.创建子进程
#include<unistd.h>
pid_t fork();
(1)fork返回值问题:给父进程返回子进程的pid,给子进程返回0,创建失败返回-1
(2)fork后子进程和父进程共享一份代码
(3)为什么要有多个返回值
#include<stdio.h>
int main(){
pid_t id = fork();
//子进程和父进程共享的代码
if(id==-1) return 1;
else if(id == 0){//子进程执行子进程的逻辑
printf("I am child");
}else{//父进程执行父进程的逻辑
printf("I am parent");
}
return 0;
}
进程切换与调度
1.进程是基于时间片轮转进行切换的,通俗来将就是每个进程执行一小段时间,轮流执行。
2.并行、并发
(1)并行:多个进程在两个CPU下分别运行
(2)并发:多个进程在一个CPU下采用进程切换的方式运行
3.进程的切换:当某个进程切换时将数据存储到寄存器中(存储的数据称为进程的上下文数据,对上下文进行存储的行为称为保护上下文),通过时间片轮转的方式对进程进行切换,当再次轮到该进程执行时,再将寄存器中的数据归还给该进程。
4.进程调度过程详解
(1)进程有两个队列,一个是活跃进程,另一个是过期进程,分别用active指针和expired指针标识,当活跃进程执行完毕后,将两个指针的指向进行交换。如果在活跃进程调度期间有新的进程加入,则将新进程加入过期进程。
(2)无论活跃进程还是过期进程都由三个部分组成,分别为nr_active、bitmap{5]、queue[140]。
(3)nr_active:保存queue队列中一共有多少个进程
(4)queue[140]:该队列中140个空间仅使用[100,139]这40个空间,每个空间都是一个队列,代表了一个优先级,通过±40来映射优先级的[60,99];当有对应优先级的进程被调度时,则在对应的空间位置进行尾插。
(5)bitmap[5]:用于判断queue中那个位置有进程需要被调度,bitmap每个空间都是long类型,long类型为32位,所以bitmap一共32*5=160个比特位。虽然有160个比特位,但是仅使用140个,通过位运算即可判断queue中那个位置有进程需要被调度。