操作系统实验(1):定时中断处理

来源:互联网 发布:socket java面试题 编辑:程序博客网 时间:2024/06/06 05:05

一、实验内容

模拟中断事件的处理。

 

二、实习目的

现代计算机系统的硬件部分都设有中断机构,它是实现多道程序设计的基础。中断机构能发现中断事件,且当发现中断事件后迫使正在处理器上执行的进程暂时停止执行,而让操作系统的中断处理程序占有处理器去处理出现的中断事件。对不同的中断事件,由于它们的性质不同,所以操作系统应采用不同的处理。通过实习了解中断及中断处理程序的作用。本实习模拟“ 时钟中断事件” 的处理,对其它中断事件的模拟处理,可根据各中断事件的性质确定处理原则,制定算法,然后依照本实习,自行设计。

 

三、实验题目

模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序。

[提示]:(1) 计算机系统工作过程中,若出现中断事件,硬件就把它记录在中断寄存器中。中断寄存器的每一位可与一个中断事件对应,当出现某中断事件后,对应的中断寄存器的某一位就被置成―1‖。

处理器每执行一条指令后,必须查中断寄存器,当中断寄存器内容不为―0‖时,说明有中断事件发生。硬件把中断寄存器内容以及现行程序的断点存在主存的固定单元,且让操作系统的中断处理程序占用处理器来处理出现的中断事件。操作系统分析保存在主存固定单元中的中断寄存器内容就可知道出现的中断事件的性质,从而作出相应的处理。本实习中,用从键盘读入信息来模拟中断寄存器的作用,用计数器加 1 来模拟处理器执行了一条指令。每模拟一条指令执行后,从键盘读入信息且分析,当读入信息=0 时,表示无中断事件发生,继续执行指令;当读入信息=1 时,表示发生了时钟中断事件,转时钟中断处理程序。

 

2)假定计算机系统有一时钟,它按电源频率( 50Hz)产生中断请求信号,即每隔 20毫秒产生一次中断请求信号,称时钟中断信号,时钟中断的间隔时间( 20 毫秒)称时钟单位。    学生可按自己确定的频率在键盘上键入―0‖或―1‖来模拟按电源频率产生的时钟中断信号。

(3) 中断处理程序应首先保护被中断的现行进程的现场(通用寄存器内容、断点等),现场信息可保存在进程控制块中;然后处理出现的中断事件,根据处理结果修改被中断进程的状态;最后转向处理器调度,由处理器调度选择可运行的进程,恢复现场使其运行。本实习主要模拟中断事件的处理,为简单起见可省去保护现场和处理器调度的工作。

(4) 为模拟时钟中断的处理,先分析一下时钟中断的作用。利用时钟中断可计算日历时钟,也可作定时闹钟等。    计算日历时钟——把开机时的时间(年、月、日、时、分、秒)存放在指定的称为―日历时钟‖的工作单元中,用一计时器累计时钟中断次数。显然,根据时钟中断的次数和时钟单位( 20 毫秒)以及开机时的日历时钟可计算出当前的精确的日历时钟(年、月、日、时、分、秒)。因此,可按需要计算出一个作业装入时的时间,一个作业撤离时的时间,终端用户使用终端的时间,以及其它场合需要确定的时间。    定时闹钟——对需要定时的场合,例如,处理器调度采用―时间片轮转‖策略调度时,可把轮到运行的进程的时间片值(以时钟单位计算)送到称为―定时闹钟‖的工作单元中,每产生一次时钟中断就把定时闹钟值减 1,当该值为―0‖时,表示确定的时间已到,起到定时的作用。(5) 本实习的模拟程序可由两部分组成,一部分是模拟硬件产生时钟中断,另一部分模拟操作系统的时钟中断处理程序。模拟程序的算法如图 1-1。其中,保护现场和处理器调度的工作在编程序时可省去。约定处理器调度总是选择被中断进程继续执行。(6) 按模拟算法设计程序,要求显示或打印开机时间、定时闹钟初值、定时闹钟为―0‖时的日历时钟。确定三个不同的定时闹钟初值,运行设计的程序,观察得到的结果。

 

四、实验流程图及过程

时钟中断模拟处理算法流程图设计如下:

 

 

算法设计过程如下

① 输入当时当地时间模拟开机时间:

<span style="font-size:18px;">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);  //输出当地当时时间</span>

 

② 设定时钟和时间片,模拟计算机中断处理程序


<span style="font-size:18px;">//设置时钟闹铃alarm;时间片为timer ,count1记录中断次数,count记录指令执行总次数次数 int timer,alarm; printf("请输入闹铃alarm和时间片timer\n"); scanf("%d%d",&alarm,&timer); int alarm1=alarm; int count=0,count1=0,input; while(alarm!=0) { do{ printf("已执行完一条指令!\n"); count++; printf("\n主程序的计数器为:%d\n",count-count1); printf("请输入0或1(0代表无中断:1代表中断):\n");  scanf("%d",&input); //键盘读取输入  模拟系统是否产生中断  }while(input==0); //如果输入0,代表无中断,一直循环执行指令  if(input==1)//代表产生了中断  printf("产生中断,执行中断处理程序,保护中断现场\n中断计数器为:%d\n",count1+1);  count1++; alarm--; if(alarm!=0) printf("处理器调度完成!\n");  }</span>

③ 中断计数器偏差处理

<span style="font-size:18px;">//对硬件的模拟,当count1出现偏差时的处理 p=count1*timer;   //每次中断处理2s  p是总的中断处理时间 a=(int)count1*timer; if((p-a)>=0.5) p=a+1; else p=a; </span>

④ 输出中断处理后的时间

<span style="font-size:18px;">//中断结束后的时间=原始时间+中断次数*时间片t=t+alarm1*timer;printf(ctime(&t)) ; </span>

五、实验结果

当从键盘输入1,模拟中断产生,中断计数器加1,闹钟减1,执行中断处理程序,主程序计数器不变。

当从键盘输入0,模拟无中断产生,主程序计数器加1,中断计数器不变。

 

运行结果表示成功模拟时钟中断处理。

① 编译interrupt.c文件生成可执行文件   gcc interrupt.c -o interrupt

如下如:虽然有警告但是没有报错,编译成功。

 

② 运行可执行文件interrupt   ./interrupt

如下图:可以看出运行成功。设定闹钟为3,时间片为2,处理3次中断后,输出终止时间。

 

六、实验小结

通过该实验,更加深入的了解了操作系统的中断,以及中断处理。

 

1.【中断的概念】:

 

中断,是指计算机在执行期间,系统发生了急需处理的事件,使得cpu需要马上停止当前正在执行的程序或操作,转而去处理相应的中断处理程序,待处理完后又返回处理原来被中断的位置继续执行。引发中断的事件称为中断源,中断源向cpu发出的请求中断处理信号称为中断请求,cpu收到请求去执行相应的中断处理程序称为中断响应。

 

中断禁止:如果cpu内部的处理器状态字PSW的中断允许位被清除了,就不允许cpu响应中断,这种情况下,即使产生中断源,发出了中断请求,但cpu仍然不会响应中断。

 

中断屏蔽:在中断请求产生后,系统有选择性的封锁一部分中断而允许一部分中断得到响应。

 

注意:有些中断请求是不能被屏蔽和禁止的。具有最高优先级的中断产生,cpu必须即时响应。例如,电源掉电事件多引起的中断就是不能被禁止和屏蔽的。

 

2.【中断的分类与优先级】:

中断分为内中断与外中断。

外中断是来自处理器和内存外部的中断,包括I/O设备发出的I/O中断,外部信号中断(eg:esc引发的退出),各种定时器引起的时钟中断和调试程序中设置的断点等引起的调试中断等。外中断在狭义上一般被称为中断。

内中断主要指在处理器和内存内部产生的中断。内中断一般称为陷阱或异常。包括程序运算引起的各种错误,如地址非法,校验错,页面失效,存取访问控制错,算数操作溢出,数据格式非法,出书为0,非法指令,用户程序执行特权指令,分时系统中的时间片中断以及从用户态到核心态的切换等都是陷阱的例子。

 

陷阱和中断的主要区别:

1.优先级设置不同。

2.陷阱通常由处理器正在执行的现行指令引起,而中断则是由与现行指令无关的中断源引起的。

3.陷阱处理程序提供的服务为当前进程所用,而中断处理程序提供的服务则不是为当前进程所用。

4.Cpu在执行一条指令后,下一条指令开始之前响应中断,而在一条指令执行中也可以响应陷阱。例如,执行指令非法时,尽管被执行的非法指令不能执行结束,但cpu仍可以对其进行处理。

 

   【中断优先级分级】:

unix系统中,外中断和陷阱的优先级共分为8级。为了禁止中断或者屏蔽中断,cpu的处理器字psw中也设有响应的优先级。如果中断源的优先级高于psw的优先级,则cpu响应中断;反之,cpu屏蔽该中断。

 

    3.【软中断】:

来源于UNIX系统。软中断对应硬中断。通过硬件产生响应的中断请求,称为硬中断。而软中断,实是指在通信进程之间通过模拟硬中断而实现的一种通信方式。中断源发出软中断信号后,cpu或者接收进程在“适当的时机”进行中断处理或者完成软中断所对应的功能。这里“适当的时机”,表示接收中断信号的进程需等到该接收进程得到处理器之后才能进行。如果该接收进程时占据处理器的,则该接收进程在接收到中断信号后将立即转去执行该软中断信号所对应的功能。

 

4.【中断处理过程】:

一旦cpu响应中断,就转去中断处理程序,系统就开始中断处理。中断处理过程如下:

① Cpu检查响应中断的条件是否满足。

     Cpu响应中断条件:有中断请求;cpu允许中断;

② 如果cpu响应中断,cpu就关中断,进入不再响应中断状态。

③ 保护被中断现场,以确保能在中断处理结束后返回中断点。系统需保存当前处理状态字PSW和程序计数器PC等的值。这些值一般板寸在特定堆栈或硬件寄存器中。

④ 分析中断原因,寻找并调用中断处理子程序。同时发生多个中断请求时,处理优先级最高的中断源发出的中断请求。针对不同的中断源编制有不同的中断处理子程序(陷阱处理子程序)。浙西额子程序的入口地址(或陷阱指令的入口地址)存放在响应的内存单元中,不同的中断源也对应着不同的处理器状态字PSW,这些不同的PSW也被存放在响应的内存单元中,与中断处理子程序入口地址一起构成中断向量。所以根据中断或陷阱种类,系统可有中断向量表迅速找到该中断响应的优先级,中断处理子程序的入口地址和对应的PSW

⑤ 执行中断处理子程序。对陷阱来讲,在有些系统中则是同故宫陷阱指令向当前执行进程发出软中断信号后条用对应的处理子程序执行。

⑥ 退出中断。恢复被中断进程的现场或调度新进程占据处理器。

⑦ 开中断,cpu继续执行。

 

5.【中断应用于设备管理器】:

处理器的高速处理和输入输出设备低速的矛盾,时设备管理要解决的一个重要的问题。为提高整体效率,减少程序直接控制方式中的cpu等待事件以及提高系统的并行工作效率,采用中断方式来控制输入输出设备和内存于cpu之间的数据传送,是和必要的。

在硬件结构上,这种方式要求cpu于输入输出设备之间有响应的中断请求线,而且在输入输出设备控制器的控制状态寄存器上有响应的中断允许位。


七、思考题

将进程调度策略结合到本实习中,可选用时间片轮转的调度策略。给每个进程分配一个相同的时间片,每产生一次时钟中断经处理后,被中断进程时间片减 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和时间片timer\n"); scanf("%d%d",&alarm,&timer); int alarm1=alarm; int count=0,count1=0,input; while(alarm!=0) { do{ printf("已执行完一条指令!\n"); count++; printf("\n主程序的计数器为:%d\n",count-count1); printf("请输入0或1(0代表无中断:1代表中断):\n"); scanf("%d",&input); //键盘读取输入  模拟系统是否产生中断 }while(input==0); //如果输入0,代表无中断,一直循环执行指令 if(input==1)//代表产生了中断  printf("产生中断,执行中断处理程序,保护中断现场\n中断计数器为:%d\n",count1+1); count1++; alarm--; if(alarm!=0) printf("处理器调度完成!\n"); } //对硬件的模拟,当count1出现偏差时的处理 p=count1*timer;   //每次中断处理2s  p是总的中断处理时间 a=(int)count1*timer; if((p-a)>=0.5) p=a+1; else p=a;//中断结束后的时间=原始时间+中断次数*时间片 t=t+alarm1*timer;printf(ctime(&t)) ; }



 

0 0
原创粉丝点击