关于Linux进程管理
进程的引入
当计算机在引入多道程序时,出现了临界资源竞争的情况,为了刻画和解决程序间的这种制约关系,提出了进程的概念,用以改善资源的利用率,提高程序的吞吐量。
进程控制块PCB
- linux系统的所有进程控制块都是通过结构体指针数组形式的数据结构来表示的(每个PCB块大约有1kb):
/*全局变量nr_task动态记录进程数*/ struct task_sturct *task[NR_TASK]={&init_task};
运行状态进程的PCB同样用结构体指针数组表示:
current_set[];
- task_struct结构体定义:
struct task_struct{ ... unsigned short uid; int pid; ... volatile long state; long prority; unsigned long rt_protity; long counter; unsigned long policy; ... struct task_struct *next_task, *prev_task; struct task_struct *next_run, *prev_run; struct task+struct *p_opptr, *pptr, *p_cptr, *pysptr, *p_ptr; ... };
数据成员说明:
uid:用户标识;
pid:进程标识;
state:进程状态标识;
1)可运行状态
2)可中断阻塞状态
3)不可中断阻塞状态
4)僵死状态
5)暂停状态
6)交换状态
protity:进程优先级;
counter:优先级计数器,用于进程轮转调度算法;
policy:进程调度策略;
next_task,prev_task:PCB双向链表指针;
p_opptr ...:指明进程家族间的关系,分别为祖父进程,父进程,子进程,以及新老进程指针;
进程属性
- 进程ID:PID,进程唯一标志符;
- 父进程ID:PPID;
- 启动进程的用户ID:UID;
- 所归属的组ID:GID;
- 进程执行的优先级;
- 进程连接终端
优先级问题
谦让度:标识进程之间资源竞争能力,高谦让度的进程,资源竞争能力弱。负值或0表示最高优先级,对其他进程不谦让。谦让度的值一般为:-20~19;当前硬件发展速度非常快,一般我们是不设置进程优先级的,除非有进程失控而疯狂的抢占资源;
在创建进程时,nice可以为进程设置谦让值,但进程优先级的值为父进程shell优先级的值与nice所指定的谦让度相加的结果。即,利用nice指定的值是一个增量,而不是优先级的绝对值。
运行 a.out 程序,并为它指定谦让度增量为5:
nice -n 5 a.out &
利用renice来更改谦让度:
renice 谦让度 PID
进程调度算法简介
程序使用cpu的三种模式:I/O密集型、计算密集型和平衡型。对于I/O密集型程序,响应时间非常重要,响应时间不及时,和可能丢失数据;对于计算密集型程序,cpu的周转时间非常重要;对于平衡型程序,协调响应和cpu周转的工作最重要。
进程周转时间:等待进入内存的时间,在就绪队列中等待的时间,在 CPU中执行的时间和I/O操作的时间的总和。
FCFS算法
FCFS(frist come first serve),也叫FIFO算法,先来先执行。短任务执行可能会非常慢,因为前面的进程可能占用很长时间,造成平均响应时间过长。
时间片轮转算法
目的是改善短程序响应时间长的问题。方法是周期性的对进程进行切换。该算法最关键的时间片的选择,时间片过长和FIFO算法区别不大,时间片过短,进程频繁切换的开销大于执行程序的开销,系统效率降低。
STCF算法
STCF算法全称:short time to complete frist。核心是每个进程都有优先级,短进程的优先级要高于长进程的优先级。STCF算法分为:非抢占式和抢占式两类。非抢占式就是让已经在cpu上运行的程序执行到结束或者阻塞,然后在就绪队列中选择执行时间最短的程序来执行。而抢占式是,每当有新进程进入就绪队列时,都会去判断当前运行进程和新进程的执行时间长短,选择执行时间短的进程运行,及永远保证cpu运行的是所有进程中执行时间最短的进程。该算法有个非常明显的缺点:长任务进程无法执行。还有该算法的关键点是如何预测进程所需的执行时间。
优先级调度算法
解决了STCF算法中长任务进程饥饿的问题,而暴露出的短任务会饥饿的问题,可以通过动态调整优先级来解决。实际上动态调整优先级(称为权值)+ 时间片轮转的策略正是Linux系统进程调度的策略之一的分时调度策略,调度过程如下:
(1) 创建任务指定采用分时调度策略,指定优先级nice的值(-20~19) (2) 依据nice的值确定在cpu上的执行时间 (3) 如果没有等待资源,则将该任务加入就绪队列中 (4) 调度程序遍历就绪队列,通过对动态优先级的计算,选择计算结果最 大的去执行。当时间片用完时或进程主动放弃cpu时,该任务就重新放回就 绪队列队尾或等待队列中。 (5) 调度程序重新按照(4)的方式调度进程。 (6) 当调度程序发现所有就绪队列中的进程的权值都不大于0时,重复(2) 的过程
现代OS通常都会采用混合调度算法。如:将不同的进程分为几个大类,每个大类有不同的优先级,不同大类的进程调度取决于大类的优先级,同一个大类的进程调度采用时间片轮转算法来实现。