《太原理工大學操作系統(tǒng)實驗報告.doc》由會員分享,可在線閱讀,更多相關(guān)《太原理工大學操作系統(tǒng)實驗報告.doc(21頁珍藏版)》請在裝配圖網(wǎng)上搜索。
課程名稱: 操作系統(tǒng)B
實驗項目: 操作系統(tǒng)實驗
實驗地點: 實驗樓209
專業(yè)班級: 軟件
學生姓名: 學號:
指導教師: 方昀
2015 年 11 月 30
目 錄
實驗一 幾種操作系統(tǒng)的界面 1
一、目的和要求 1
二、內(nèi)容 1
實驗二 進程調(diào)度程序設計 2
一、目的和要求 2
二、示例 2
實驗三 存儲管理程序設計 9
一、目的和要求 9
二、提示 9
實驗一 幾種操作系統(tǒng)的界面
一、目的和要求
(一) 目的
本實驗的目的是使學生熟悉1—2種操作系統(tǒng)的界面,在熟練使用機器的基礎上,能了解各種操作命令和系統(tǒng)調(diào)用在系統(tǒng)中的大致工作過程。也就是通過操作系統(tǒng)的外部特征,逐步深入到操作系統(tǒng)的內(nèi)部實質(zhì)內(nèi)容中去。
(二) 要求
1. 能熟練的在1—2種操作系統(tǒng)的環(huán)境下工作,學會使用各種命令,熟悉系統(tǒng)提供的各種功能,主動而有效地使用計算機。
2. 熟悉系統(tǒng)實用程序的調(diào)用方法和各種系統(tǒng)調(diào)用模塊的功能和作用
二、內(nèi)容
在某種操作系統(tǒng)的環(huán)境下建立、修改、運行、打印源程序和結(jié)果,最后撤消一個完整的程序。
提示:可按下述步驟進行
1. 編寫一個完整的源程序,通過編輯命令送入機器,建立源程序文件;
2. 編譯該源文件,建立相應的目標文件;
3. 編譯有錯時,再用編輯命令修改源文件,消除全部詞法和語法錯誤;
4. 連接目標文件,形成可執(zhí)行文件;
5. 執(zhí)行該文件,得到結(jié)果;
6. 打印輸出源程序和運行結(jié)果;
7. 撤消本次實驗中形成的所有文件。
三、實驗步驟及程序流程圖
1)Dos命令行。
1. 按住Windows鍵+R輸入notepad回車調(diào)出記事本。
2. 編輯一個java程序選擇另存為d:。
3. 按住Windows鍵+R輸入cmd回車。
4. 進入Dos界面鍵入d:。
5. 輸入dir查看java文件,使用javac命令進行編輯
四、程序清單(據(jù)情況而定)
class demo
{
public static void main(String [] args)
{
System.out.print("這是一個java例子");
}
}
五、討論、心得
本次實驗是在Windows10系統(tǒng)下進行的,通過對一個Java小程序的編譯連接熟悉對Win10的操作以及DOS命令的使用。
試驗中使用到的DOS工具:
查看目錄:dir
編輯:javac
通過本次實驗,進一步熟悉了對操作系統(tǒng)尤其是DOS 命令的使用,初步了解了部分操作命令和系統(tǒng)調(diào)用在系統(tǒng)中的大致工作過程,通過實踐也加深了對老師課堂一些所講知識的理解。
實驗二 進程調(diào)度程序設計
一、目的和要求
(一) 目的
進程是操作系統(tǒng)最重要的概念之一,進程調(diào)度是操作系統(tǒng)的主要內(nèi)容,本實驗要求學生獨立地用高級語言編寫一個進程調(diào)度程序,調(diào)度算法可任意選擇或自行設計,本實驗可使學生加深對進程調(diào)度和各種調(diào)度算法的理解。
(二) 要求
1. 設計一個有幾個進程并發(fā)執(zhí)行的進程調(diào)度程序,每個進程由一個進程控制塊(PCB)表示,進程控制塊通常應包括下述信息:進程名,進程優(yōu)先數(shù),進程需要運行的時間,占用CPU的時間以及進程的狀態(tài)等,且可按照調(diào)度算法的不同而增刪。
2. 調(diào)度程序應包含2—3種不同的調(diào)度算法,運行時可以任選一種,以利于各種方法的分析和比較。
3. 系統(tǒng)應能顯示或打印各進程狀態(tài)和參數(shù)的變化情況,便于觀察。
二、示例
1. 題目 本程序可選用優(yōu)先數(shù)法或簡單輪轉(zhuǎn)法對五個進程進行調(diào)度。每個進程處于運行R(run)、就緒W(wait)和完成F(finish)三種狀態(tài)之一,并假定起始狀態(tài)都是就緒狀態(tài)W。
為了便于處理,程序中進程的運行時間以時間片為單位計算。各進程的優(yōu)先數(shù)或輪轉(zhuǎn)時間片數(shù)、以及進程需要運行的時間片數(shù),均由偽隨機數(shù)發(fā)生器產(chǎn)生。
進程控制塊結(jié)構(gòu)如表2-1所示:
表2-1 PCB
進程標識符
鏈指針
優(yōu)先數(shù)/輪轉(zhuǎn)時間片數(shù)
占用CPU時間片數(shù)
進程所需時間片數(shù)
進程狀態(tài)
進程控制塊鏈結(jié)構(gòu)如圖2-1所示:
RUN HEAD TAIL
…
圖2-1 進程控制塊鏈結(jié)構(gòu)
其中:RUN—當前運行進程指針;
HEAD—進程就緒鏈鏈首指針;
TAIL—進程就緒鏈鏈尾指針。
2. 算法與框圖 程序框圖如圖2-2所示。
圖2-2 進程調(diào)度框圖
(1)優(yōu)先數(shù)法。 進程就緒鏈按優(yōu)先數(shù)大小從大到小排列,鏈首進程首先投入運行。每過一個時間片,運行進程所需運行的時間片數(shù)減1,說明它已運行了一個時間片,優(yōu)先數(shù)也減3。理由是該進程如果在一個時間片中完成不了,優(yōu)先級應降低一級。接著比較現(xiàn)行進程和就緒鏈鏈首進程的優(yōu)先數(shù),如果仍是現(xiàn)行進程高或者相同,就讓現(xiàn)行進程繼續(xù)運行,否則,調(diào)度就緒鏈鏈首進程投入運行。原運行進程再按其優(yōu)先數(shù)大小插入就緒鏈,且改變它們對應的進程狀態(tài),直至所有進程都運行完各自的時間片數(shù)。
(2)簡單輪轉(zhuǎn)法。 進程就緒鏈按各進程進入的先后次序排列,鏈首進程首先投入運行。進程每次占用處理機的輪轉(zhuǎn)時間按其重要程度登入進程控制塊中的輪轉(zhuǎn)時間片數(shù)記錄項(相應于優(yōu)先數(shù)法的優(yōu)先數(shù)記錄項位置)。每過一個時間片,運行進程占用處理機的時間片數(shù)加1,然后比較占用處理機的時間片數(shù)是否與該進程的輪轉(zhuǎn)時間片數(shù)相等,若相等說明已到達輪轉(zhuǎn)時間,應將現(xiàn)運行進程排到就緒鏈末尾,調(diào)度鏈首進程占用處理機,且改變它們的進程狀態(tài),直至所有進程完成各自的時間片。
三、代碼:
#include
#include
#define furthest 5
struct process /*PCB STRUCTURE*/
{
int id;
int priority;
int cputime;
int alltime;
char state;
int next;
}prochain[furthest - 1];
int procnum;
int rand();
int algo;
int run, head, tail, j;
void print();
void insert(int q);
void insert2();
void timesch();
void init();
void prisch();
int main() /*MAIN PROGRAM*/
{
agan: printf("type the algorithm is (1:RR,2:PRIO):");
scanf("%d", &algo);
if (algo == 2)
{
printf("output of priority.\n");
init();
prisch();
}
else
{
if (algo == 1)
{
printf("output of round robin.\n");
init();
timesch();
}
else
{
printf("try again,please\n");
goto agan;
}
}
for (j = 1; j <= 40; j++)
{
printf("=");
}
printf("\n\n");
for (j = 1; j <= 40; j++)
{
printf("=");
}
printf("\n\n");
printf("system finished\n");
getchar();
}
void print() /*PRINT THE RUNNING PROCESS,WAITING
QUEUE AND PCB SEQUENCE LIST*/
{
int k, p;
for (k = 1; k <= 40; k++)
printf("=");
printf("\nrunning proc. ");
printf("waiting queue.");
printf("\n %d ", prochain[run].id);
p = head;
while (p != 0)
{
printf("%5d", p);
p = prochain[p].next;
}
printf("\n");
for (k = 1; k <= 40; k++)
printf("=");
printf("\n");
printf(" id ");
for (k = 1; k
#include
#include
using namespace std;
struct pageTable//定義頁表
{
int address;//地址
int page;//頁號
int block;//塊號
struct pageTable *next;
};
typedef struct pageTable PAGETABLE;
PAGETABLE *pt;
const int first_memory = 1000;//內(nèi)存首地址
int work[320];//作業(yè)
int index, offset;//index是作業(yè)的頁號,offset為頁內(nèi)偏移地址
PAGETABLE*oldPtr;//minPtr指向駐留時間最久的頁
int count1;//記數(shù)器,用于記錄發(fā)生的缺頁數(shù)
bool is_LRU = false;//是否是LRU算法
void init();
void insertPage();
void pushback_Page(PAGETABLE *, PAGETABLE *);
void print(PAGETABLE *);
void run(int);
void find_FIFO();
void find_LRU();
void main(void)
{
int i = 0;
while (1)
{
cout << "\nPlease select a number(1,2,0)" << endl;
cout << " 1--先進先出算法(FIFO)" << endl;
cout << " 2--最久未使用算法(LRU)" << endl;
cout << " 0--程序結(jié)束" << endl;
cin >> i;
if (i == 1)
{
cout << "\nThis is a example for FIFO:" << endl;
is_LRU = false;
init();//構(gòu)造頁表和內(nèi)存
}
else if (i == 2)
{
cout << "\nThis is a example for LRU:" << endl;
is_LRU = true;
init();//構(gòu)造頁表和內(nèi)存
}
else if (i == 0)
{
exit(1);
}
}
}
void init()
{
double rate;
int count = 0;//記數(shù)器初值為0
srand(time(NULL));
pt = new PAGETABLE;
pt->next = NULL;
for (int i = 0; i<4; i++)
{
insertPage();
}
oldPtr = pt->next;//初始化最久的頁面
cout << "頁表初始狀態(tài)為:" << endl;
print(pt);
for (int k = 0; k<320; k++)//初始化作業(yè)
{
work[k] = k;
}
for (int f = 0; f<53; f++)//作業(yè)運行
{
int m, m1, m2;
m = rand() % 320;
if (m == 319)
m = 318;
run(m);
print(pt);
run(m + 1);
print(pt);
if (m == 0)
m1 = 0;
else
m1 = rand() % m;
run(m1);
print(pt);
run(m1 + 1);
print(pt);
m2 = rand() % (320 - m) + m - 1;
if (m2<0)
m2 = 318;
if (m2 == 319)
m2 = 318;
run(m2);
print(pt);
run(m2 + 1);
print(pt);
}
rate = (double)count / 318 * 100;
cout << "\n\n 缺頁率為:" << rate << "%" << endl;
}
/* 構(gòu)建頁表*/
void insertPage()
{
PAGETABLE *newPage;
static int id = 99;
static int blockId = -1;
id++;
blockId++;
if (blockId == 4)
blockId = 0;
newPage = (PAGETABLE *)malloc(sizeof(PAGETABLE));
if (newPage != NULL)
{
newPage->address = id;
newPage->page = -1;
newPage->block = blockId;
newPage->next = NULL;
pushback_Page(pt, newPage);
}
else
cout << "沒有內(nèi)存足夠的空間為頁表分配!" << endl;
}
void pushback_Page(PAGETABLE *queue, PAGETABLE *item)
{
PAGETABLE *previous, *current;
previous = queue;
current = queue->next;
while (current != NULL)
{
previous = current;
current = current->next;
}
previous->next = item;
}
void print(PAGETABLE *ptr)
{
PAGETABLE *temp;
temp = ptr->next;
cout << " 頁號 " << " 塊號 " << endl;
while (temp != NULL)
{
cout << " " << temp->page << " " << temp->block << endl;
temp = temp->next;
}
}
void run(int num)
{
int universal;
PAGETABLE *previous, *current;
index = work[num] / 10;//程序所在的頁號
offset = work[num] % 10;//頁內(nèi)的位移量
previous = pt;
current = previous->next;
while (current != NULL && current->page != index)
{
previous = current;
current = current->next;
}
if (current == NULL)
{
cout << "\n作業(yè)" << num << "沒有在內(nèi)存,發(fā)生缺頁中斷" << endl;
count1++;
if (is_LRU == false)//FIFO算法
{
find_FIFO();
}
else//LRU算法
{
find_LRU();
}
}
else
{
if (is_LRU == false)//FIFO算法
{
universal = first_memory + (current->block) * 10 + offset;
cout << "\n作業(yè)" << num << "所在內(nèi)存的物理地址為 " << universal << endl;
}
else
{
if (current->next == NULL)
{
universal = first_memory + (current->block) * 10 + offset;
cout << "\n作業(yè)" << num << "所在內(nèi)存的物理地址為 " << universal << endl;
}
else
{
PAGETABLE *temp, *ptr;
temp = current;
previous->next = current->next;
ptr = pt->next;
while (ptr->next != NULL)
{
ptr = ptr->next;
}
ptr->next = temp;
temp->next = NULL;
universal = first_memory + (temp->block) * 10 + offset;
cout << "\n作業(yè)" << num << "所在內(nèi)存的物理地址為 " << universal << endl;
}
}
}
}
void find_FIFO()//先進先出頁面置換算法
{
PAGETABLE *pos;
int universal;
pos = pt->next;
if (oldPtr == NULL)
{
oldPtr = pt->next;
}
while (pos != NULL && pos->page != -1)
{
pos = pos->next;
}
if (pos == NULL)//出現(xiàn)缺頁中斷
{
cout << "******頁面開始置換******" << endl;
oldPtr->page = index;
universal = first_memory + (oldPtr->block) * 10 + offset;
cout << "置換后作業(yè)在內(nèi)存的物理地址為 " << universal << endl;
oldPtr = oldPtr->next;
}
else//頁面還未裝完
{
pos->page = index;
universal = first_memory + (pos->block) * 10 + offset;
cout << "作業(yè)在內(nèi)存的物理地址為 " << universal << endl;
}
}
void find_LRU()//最久置換算法
{
PAGETABLE *pos;
int universal;
pos = pt->next;
while (pos != NULL && pos->page != -1)
{
pos = pos->next;
}
if (pos == NULL)//出現(xiàn)缺頁中斷
{
cout << "******頁面開始置換******" << endl;
PAGETABLE *temp;
temp = pt->next;
temp->page = index;
universal = first_memory + (temp->block) * 10 + offset;
cout << "置換后作業(yè)在內(nèi)存的物理地址為 " << universal << endl;
}
else//頁面還未裝完
{
pos->page = index;
universal = first_memory + (pos->block) * 10 + offset;
cout << "作業(yè)在內(nèi)存的物理地址為 " << universal << endl;
}
}
四、結(jié)果:
五、心得
本次試驗的目的是通過請求頁式存儲管理中頁面置換算法的模擬設計,來了解虛擬存儲技術(shù)的特點,掌握請求頁式存儲管理的頁面置換算法。試驗中主要使用了FIFO算法,即總是先淘汰最先進入內(nèi)存的頁面(駐留最久的頁面),實現(xiàn)時只需要把一個進程也調(diào)入內(nèi)存的頁面按先后次序鏈接成一個隊列,并設置一個指針,總是指向最老的頁面。
FIFO的主要的缺點是沒有考慮到有的頁面會經(jīng)常被訪問,因此并沒有辦法保證這種頁面能夠保留在內(nèi)存中,可能使得利用率較低。
通過本次試驗加深了對相應算法的理解,鞏固了相關(guān)的知識和使用的方法。
鏈接地址:http://m.appdesigncorp.com/p-6523448.html