一、调研进程的调度算法
1、先来先服务算法(FCFS, First Come First Serve)
先来先服务是最简单的调度算法,按先后顺序进行调度。
按照作业提交或进程变为就绪状态的先后次序,分派CPU;当前作业或进程占用CPU,直到执行完或阻塞,才出让CPU(非抢占方式);在作业或进程唤醒后(如I/O完成),并不立即恢复执行,通常等到当前作业或进程出让CPU。最简单的算法。
2、轮转算法(Round Robin)
轮转法是让每个进程在就绪队列中的等待时间与享受服务的时间成正比例。
将系统中所有的就绪进程按照FCFS原则,排成一个队列。每次调度时将CPU分派给队首进程,让其执行一个时间片。时间片的长度从几个ms到几百ms。在一个时间片结束时,发生时钟中断。调度程序据此暂停当前进程的执行,将其送到就绪队列的末尾,并通过上下文切换执行当前的队首进程。进程可以未使用完一个时间片,就出让CPU(如阻塞)。
3、多级反馈队列算法(Round Robin with Multiple Feedback)
多级反馈队列算法是轮转算法和优先级算法的综合和发展。
设置多个就绪队列,分别赋予不同的优先级,如逐级降低,队列1的优先级最高。每个队列执行时间片的长度也不同,规定优先级越低则时间片越长,如逐级加倍。新进程进入内存后,先投入队列1的末尾,按FCFS算法调度;若按队列1一个时间片未能执行完,则降低投入到队列2的末尾,同样按FCFS算法调度;如此下去,降低到最后的队列,则按时间片轮转算法调度直到完成。仅当较高优先级的队列为空,才调度较低优先级的队列中的进程执行。如果进程执行时有新进程进入较高优先级的队列,则抢先执行新进程,并把被抢先的进程投入原队列的末尾。
4、优先级算法(Priority Scheduling)
优先级算法(Priority Scheduling)是多级队列算法的改进,平衡各进程对响应时间的要求。适用于作业调度和进程调度,可分成抢先式和非抢先式。
作业调度中的静态优先级大多按以下原则确定:由用户自己根据作业的紧急程度输入一个适当的优先级;由系统或操作员根据作业类型指定优先级;系统根据作业要求资源情况确定优先级。
进程的动态优先级一般根据以下原则确定:根据进程占用有CPU时间的长短来决定;根据就绪进程等待CPU的时间长短来决定。
5、短作业优先算法(SJF, Shortest Job First)
短作业优先又称为“短进程优先”(SPN,Shortest Process Next);这是对FCFS算法的改进,其目标是减少平均周转时间。
对预计执行时间短的作业(进程)优先分派处理机。通常后来的短作业不抢先正在执行的作业。
二、调研task_struct结构体, 理解结构体中的各个字段的含义
task_struct结构体是Linux中描述进程的结构体,它是Linux内核的一种数据结构,被装载到RAM里并且包含着进程信息
1、标识符:描述进程的唯一标识符,用来区别其他进程(PID)
2、状态:任务状态、退出代码、退出信号等
3、优先级:相对于其他进程的优先级
4、程序计数器:程序即将被执行的下条指令的地址,可以知道程序被执行到哪,CPU中一个重要的寄存器PC指针,里面存放当前执行指令的下条指令的地址
5、内存指针:包括程序代码和进程相关数据的指针还有和其他进程共享的内存块的指针
6、上下文数据:进程执行时处理器的寄存器中的数据,CPU中寄存器的值
7、I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
8、记账信息:可能包括处理器时间总和,使用时钟数总和,时间限制,记账号等
9、其他信息
三、使用代码模拟实现僵尸进程, 孤儿进程的场景
1、僵尸进程
首先写一个makefile
zombie:zombie.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f zombie
再创建一个僵尸进程zombie.c
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
int main()
{
pid_t id = fork();
if(id < 0)
{
perror("fork");
return 1;
}
else if(id > 0)
{
printf("parent[%d] is sleeping...\n",getpid());
sleep(10);
}
else
{
printf("child[%d] is begin Z..\n",getpid);
sleep(3);
exit(EXIT_SUCCESS); //子进程3秒后退出
}
return 0;
}
打开两个终端,一个运行zombie.c,一个查看进程状态
2、孤儿进程
首先写一个Makefile
orphan:orphan.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f orphan
再创建一个孤儿进程orphan.c
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
int main()
{
pid_t id = fork();
if(id < 0)
{
perror("fork");
return 1;
}
else if(id > 0)
{
printf("I am child,pid: %d\n",getpid());
sleep(10);
}
else
{
printf("I am parent,pid: %d\n",getpid);
sleep(3);
exit(0); //父进程3秒后退出
}
return 0;
}
打开两个终端,一个运行orphan.c,一个查看进程状态
四、setenv, export等环境变量相关的函数和命令
1、setenv:增加或改变环境变量
2、export:设置一个新的环境变量
3、echo:显示某个环境变量值
4、env:显示所有环境变量
5、unset:清除环境变量
6、set:显示本地定义的shell变量和环境变量