操作系統實驗-模擬中斷事件的處理

實驗四
一、實驗題目
模擬中斷事件的處理。
二、實驗內容
(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和時間片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>
在這裏插入圖片描述
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和時間片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=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+alarm1
timer;
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和時間片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)) ;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章