概述
实验四
一、实验题目
模拟中断事件的处理。
二、实验内容
(1) 计算机系统工作过程中,若出现中断事件,硬件就把它记录在中断寄存器中。中断寄存器的每一位可与一个中断事件对应,当出现某中断事件后,对应的中断寄存器的某一位就被置成“1”。
处理器每执行一条指令后,必须查中断寄存器,当中断寄存器内容不为“0”时,说明有中断事件发生。硬件把中断寄存器内容以及现行程序的断点存在主存的固定单元,且让操作系统的中断处理程序占用处理器来处理出现的中断事件。操作系统分析保存在主存固定单元中的中断寄存器内容就可知道出现的中断事件的性质,从而作出相应的处理。
本实验中,用从键盘读入信息来模拟中断寄存器的作用,用计数器加1来模拟处理器执行了一条指令。每模拟一条指令执行后,从键盘读入信息且分析,当读入信息=0时,表示无中断事件发生,继续执行指令;当读入信息=1时,表示发生了时钟中断事件,转时钟中断处理程序。
(2) 假定计算机系统有一时钟,它按电源频率(50Hz)产生中断请求信号,即每隔20毫秒产生一次中断请求信号,称时钟中断信号,时钟中断的间隔时间(20毫秒)称时钟单位。
学生可按自己确定的频率在键盘上键入“0”或“1”来模拟按电源频率产生的时钟中断信号。
(3) 中断处理程序应首先保护被中断的现行进程的现场(通用寄存器内容、断点等),现场信息可保存在进程控制块中;然后处理出现的中断事件,根据处理结果修改被中断进程的状态;最后转向处理器调度,由处理器调度选择可运行的进程,恢复现场使其运行。
本实验主要模拟中断事件的处理,为简单起见可省去保护现场和处理器调度的工作。
(4) 为模拟时钟中断的处理,先分析一下时钟中断的作用。利用时钟中断可计算日历时钟,也可作定时闹钟等。
计算日历时钟——把开机时的时间(年、月、日、时、分、秒)存放在指定的称为“日历时钟”的工作单元中,用一计时器累计时钟中断次数。显然,根据时钟中断的次数和时钟单位(20毫秒)以及开机时的日历时钟可计算出当前的精确的日历时钟(年、月、日、时、分、秒)。因此,可按需要计算出一个作业装入时的时间,一个作业撤离时的时间,终端用户使用终端的时间,以及其它场合需要确定的时间。
定时闹钟——对需要定时的场合,例如,处理器调度采用“时间片轮转”策略调度时,可把轮到运行的进程的时间片值(以时钟单位计算)送到称为“定时闹钟”的工作单元中,每产生一次时钟中断就把定时闹钟值减1,当该值为“0”时,表示确定的时间已到,起到定时的作用。
图3-1 时钟中断处理模拟算法
(5) 本实验的模拟程序可由两部分组成,一部分是模拟硬件产生时钟中断,另一部分模拟操作系统的时钟中断处理程序。模拟程序的算法如图3-1。其中,保护现场和处理器调度的工作在编程序时可省去。约定处理器调度总是选择被中断进程继续执行。
(6) 按模拟算法设计程序,要求显示或打印开机时间、定时闹钟初值、定时闹钟为“0”时的日历时钟。确定三个不同的定时闹钟初值,运行设计的程序,观察得到的结果。
三、实验过程
1、实验原理
一旦cpu响应中断,就转去中断处理程序,系统就开始中断处理。中断处理过程如下:
① Cpu检查响应中断的条件是否满足。
Cpu响应中断条件:有中断请求;cpu允许中断;
② 如果cpu响应中断,cpu就关中断,进入不再响应中断状态。
③ 保护被中断现场,以确保能在中断处理结束后返回中断点。系统需保存当前处理状态字PSW和程序计数器PC等的值。这些值一般板寸在特定堆栈或硬件寄存器中。
④ 分析中断原因,寻找并调用中断处理子程序。同时发生多个中断请求时,处理优先级最高的中断源发出的中断请求。针对不同的中断源编制有不同的中断处理子程序(陷阱处理子程序)。浙西额子程序的入口地址(或陷阱指令的入口地址)存放在响应的内存单元中,不同的中断源也对应着不同的处理器状态字PSW,这些不同的PSW也被存放在响应的内存单元中,与中断处理子程序入口地址一起构成中断向量。所以根据中断或陷阱种类,系统可有中断向量表迅速找到该中断响应的优先级,中断处理子程序的入口地址和对应的PSW。
⑤ 执行中断处理子程序。对陷阱来讲,在有些系统中则是同故宫陷阱指令向当前执行进程发出软中断信号后条用对应的处理子程序执行。
⑥ 退出中断。恢复被中断进程的现场或调度新进程占据处理器。
⑦ 开中断,cpu继续执行。
2、数据结构
//设置时钟闹铃alarm;
时间片为timer ,count1记录中断次数,
count记录指令执行总次数次数
int timer,alarm;
printf(“请输入闹铃alarm和时间片timern”);
scanf("%d%d",&alarm,&timer);
int alarm1=alarm;
int count=0,count1=0,input;
while(alarm!=0)
{
do{
printf(“已执行完一条指令!n”);
count++;
printf("n主程序的计数器为:%dn",count-count1);
printf(“请输入0或1(0代表无中断:1代表中断):n”);
scanf("%d",&input); //键盘读取输入 模拟系统是否产生中断
}while(input= =0); //如果输入0,代表无中断,一直循环执行指令 if(input= =1)//代表产生了中断
printf(“产生中断,执行中断处理程序,保护中断现场n中断计数器为:%dn”,count1+1);
count1++;
alarm–;
if(alarm!=0)
printf(“处理器调度完成!n”);
} < /span>
3、算法设计
① 输入当时当地时间模拟开机时间:
struct tm local;
char st,s[27]; //s是字符数组 所以要±48(‘0‘的ascii码是48)
time_t t;
t=time(NULL);
local=localtime(&t);
st=asctime(local);
printf("%s",st); //输出当地当时时间
② 设定时钟和时间片,模拟计算机中断处理程序
//设置时钟闹铃alarm;
时间片为timer ,count1记录中断次数,
count记录指令执行总次数次数
int timer,alarm;
printf(“请输入闹铃alarm和时间片timern”);
scanf("%d%d",&alarm,&timer);
int alarm1=alarm;
int count=0,count1=0,input;
while(alarm!=0)
{
do{
printf(“已执行完一条指令!n”);
count++;
printf("n主程序的计数器为:%dn",count-count1);
printf(“请输入0或1(0代表无中断:1代表中断):n”);
scanf("%d",&input); //键盘读取输入 模拟系统是否产生中断
}while(input= =0); //如果输入0,代表无中断,一直循环执行指令 if(input==1)//代表产生了中断
printf(“产生中断,执行中断处理程序,保护中断现场n中断计数器为:%dn”,count1+1);
count1++;
alarm–;
if(alarm!=0)
printf(“处理器调度完成!n”);
}
③ 中断计数器偏差处理
//对硬件的模拟,当count1出现偏差时的处理
p=count1timer; //每次中断处理2s p是总的中断处理时间 a=(int)count1timer;
if((p-a)>=0.5) p=a+1;
else p=a;
< /span>
④ 输出中断处理后的时间
< span style=“font-size:18px;”>
//中断结束后的时间=原始时间+中断次数时间片
t=t+alarm1timer;
printf(ctime(&t)) ;
< /span>
四、实验结果
五、体会与收获
我将进程调度策略结合到本实验中,可选用时间片轮转的调度策略。给每个进程分配一个相同的时间片,每产生一次时钟中断经处理后,被中断进程时间片减 1,时间片值=0 时,该进程优先运行,若时间片值=0 且该进程尚未运行结束,则将它排入队尾,再给它分配一个时间片,直到所有的进程运行结束。
六、源代码
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{ double p;
int a;
struct tm local;
char st,s[27];
///s是字符数组 所以要±48(‘0‘的ascii码是48)
time_t t;
t=time(NULL);
local=localtime(&t);
st=asctime(local);
printf("%s",st);
///输出当地当时时间
///记录初始时间 字符串时间转化为数组
// for(int i=0;i<27;i++)
// {
// s[i]=st;
// st++;
// }
// printf(“当前系统时间为:n”);
// for(int i=4;i<27;i++)
//s[4]-s[26]代表时间
// {
// printf("%c",s[i]);
// }
///设置时钟闹铃alarm;时间片为timer ,count1记录中断次数,count记录指令执行总次数(包括中断和不中断)
int timer,alarm;
printf(“请输入闹铃alarm和时间片timern”);
scanf("%d%d",&alarm,&timer);
int alarm1=alarm;
int count=0,count1=0,input;
while(alarm!=0)
{
do{
printf(“已执行完一条指令!n”);
count++;
printf("n主程序的计数器为:%dn",count-count1);
printf(“请输入0或1(0代表无中断:1代表中断):n”);
scanf("%d",&input);
///键盘读取输入 模拟系统是否产生中断
}while(input= =0);
///如果输入0,代表无中断,一直循环执行指令
if(input==1)///代表产生了中断
printf(“产生中断,执行中断处理程序,保护中断现场n中断计数器为:%dn”,count1+1);
count1++;
alarm–;
if(alarm!=0)
printf(“处理器调度完成!n”);
} ///对硬件的模拟,当count1出现偏差时的处理
p=count1timer;
///每次中断处理2s p是总的中断处理时间
a=(int)count1timer;
if((p-a)>=0.5)
p=a+1;
else p=a;
///中断结束后的时间=原始时间+中断次数时间片
t=t+alarm1*timer; printf(ctime(&t)) ;
}
最后
以上就是还单身电源为你收集整理的操作系统实验-模拟中断事件的处理的全部内容,希望文章能够帮你解决操作系统实验-模拟中断事件的处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复