进度调度切换

tips:

进程=内核数据结构(PCB/task_struct)+代码和数据

UID:每个用户对应的id

进程分类 & 进程关系

僵尸进程

父在子死

进程退出

  1. 代码不会再执行了,系统可以立即释放对应代码和数据
  2. 进程退出码保存在自己task_struct内部
  3. 管理结构task_struct必须被OS维护起来,方便用户未来进行获取进程退出的信息

孤儿进程

父退,子在

子进程会被系统自动领养

被领养的进程被称为孤儿进程

默认进程一般会转为后台运行

进程创建&销毁

创建进程时,先创建内核数据结构(task_struct),后加载代码和数据

释放时,先释放代码和数据,最后释放task_struct

在进程结束,其父进程没结束时,该进程为僵尸状态。task_struct一直不回收

除非父进程读取结束的子进程,子进程就会从Z到X,并释放task_struct

优先级

指的是task_struct的优先级, 与CPU调用有关, 

是什么

获得某种资源的先后顺序,比如,打饭时排队的本质就是在确认优先级。

为什么

本质是目标资源比较少,

怎么办

task_struct中有优先级属性,特定的几个int变量表示优先级,数字越小,优先级变高(类似排名)

PRI:priority,优先级

NI:nice,优先级的nice值(优先级修正数据)

最终优先级=pri(default80)+nice

nice值为[-20,19],40个值(与struct task_struct*  [140]中的40个分时切片任务有关)

为什么nice要限制在可控范围内?

保证资源被进程均匀分布

进程切换

概念储备

  • 时间片,时间片到了,进程就要被切换
  • linux是基于时间片,进行调度轮换的
  • 一个进程在时间片到了的时候,并不一定跑完了,可以在任何时间被重新调度切换
  • 理解进度切换:就像 大学期间被征兵入伍,应先通知学校,学校会保留学籍,未来退伍后恢复学籍,从此再次开始学籍

很重要的两步:保留和恢复上下文数据

切换过程和理解

进程在运行时,会有很多临时数据,都在cpu寄存器中储存,如eax,ebx,eflag,ecs...

eip:当前正在执行指令的下条指令地址

ir;指令寄存器,就是正在执行的指令

进行切换的核心:上下文数据的保存和恢复

上下文保护:

切走:将相关寄存器内容保护起来

切回:将历史保存的寄存器数据,恢复到寄存器中

临时保存地址不在cpu,在内存中的段中,可理解为直接存储在PCB(task_struct)中

每次保存完数据后,cpu是全新的

硬件上,只有一个寄存器。但被所有进程共享

task_struct按优先级调用

与优先级有关

CPU调用runquequ不是FIFO,二是按照优先级映射到一个struct task_struct*  [140]数组上,依次调用

前100是实时进程,不用管。后40个分片进程

板书

这是一个比较大的项目,需要涉及到操作系统的相关知识。以下是一个简单的实现示例,仅供参考。 首先,我们需要定义进程的结构体和队列: ```C typedef struct process{ int pid; // 进程ID int priority; // 优先级 int burst; // 运行时间 int remaining; // 剩余时间 int wait; // 等待时间 int turnaround; // 周转时间 }PROCESS; typedef struct queue{ PROCESS* data[MAX_PROCESS]; int front, rear; }QUEUE; ``` 其中,`MAX_PROCESS`是进程队列的最大长度。接下来是基于优先权的进程调度算法的主要代码: ```C void priorityScheduling(PROCESS* processes[], int n){ QUEUE* q = createQueue(); int currentTime = 0; // 当前时间 int completed = 0; // 已完成的进程数 while(completed < n){ // 将到达时间小于等于当前时间的进程加入队列 for(int i = 0; i < n; i++){ if(processes[i]->burst > 0 && processes[i]->remaining == processes[i]->burst && processes[i]->arrival <= currentTime){ enqueue(q, processes[i]); } } // 如果队列为空,则时间跳到下一个进程到达的时间 if(isEmpty(q)){ int minArrival = INT_MAX; for(int i = 0; i < n; i++){ if(processes[i]->burst > 0 && processes[i]->remaining == processes[i]->burst && processes[i]->arrival < minArrival){ minArrival = processes[i]->arrival; } } currentTime = minArrival; continue; } // 从队列中选择优先级最高的进程运行 PROCESS* p = dequeue(q); p->wait += currentTime - p->turnaround; p->remaining--; currentTime++; // 如果进程已完成,则计算周转时间 if(p->remaining == 0){ completed++; p->turnaround = currentTime - p->arrival; } else{ // 如果还有剩余时间,则将进程重新加入队列 enqueue(q, p); } } // 输出结果 printResult(processes, n); } ``` 在上述代码中,`createQueue()`、`enqueue()` 和 `dequeue()` 函数均为队列相关的操作函数。`printResult()` 函数用于输出各个进程的等待时间、周转时间等统计信息。接下来是基于时间片轮转调度算法的主要代码: ```C void roundRobinScheduling(PROCESS* processes[], int n, int timeQuantum){ QUEUE* q = createQueue(); int currentTime = 0; // 当前时间 int completed = 0; // 已完成的进程数 while(completed < n){ // 将到达时间小于等于当前时间的进程加入队列 for(int i = 0; i < n; i++){ if(processes[i]->burst > 0 && processes[i]->remaining == processes[i]->burst && processes[i]->arrival <= currentTime){ enqueue(q, processes[i]); } } // 如果队列为空,则时间跳到下一个进程到达的时间 if(isEmpty(q)){ int minArrival = INT_MAX; for(int i = 0; i < n; i++){ if(processes[i]->burst > 0 && processes[i]->remaining == processes[i]->burst && processes[i]->arrival < minArrival){ minArrival = processes[i]->arrival; } } currentTime = minArrival; continue; } // 从队列头开始,每次运行一个时间片 PROCESS* p = dequeue(q); p->wait += currentTime - p->turnaround; p->remaining -= timeQuantum; currentTime += timeQuantum; // 如果进程已完成,则计算周转时间 if(p->remaining <= 0){ completed++; p->turnaround = currentTime - p->arrival + p->remaining; } else{ // 如果还有剩余时间,则将进程重新加入队列 enqueue(q, p); } } // 输出结果 printResult(processes, n); } ``` 在上述代码中,`timeQuantum` 表示每个进程运行的时间片长度。需要注意的是,如果 `timeQuantum` 过小,会增加上下文切换的开销;如果 `timeQuantum` 过大,会导致响应时间较长。因此,选择合适的时间片长度是很重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值