第一篇:操作系統第一次實驗報告(大全)
操作 系統 實驗報告
實驗名稱:
線程 控制實驗
計算機科學與技術學院
目錄
一、實驗目的和要求 2 二、實驗內容 2 三、實驗步驟 2 四、實驗結果與分析 3 1.單線程 3 2.單線程(睡眠 4s)3 3.多線程 4 4.多線程(每個子線程睡眠 1s)4 5.單線程與多線程對比 5 五、程序源代碼 5 1.單線程實驗代碼 5 2.單線程實驗代碼 6 六、實驗體會 7
一、實驗目的和要求
通過本實驗掌握在 Linux 操作系統中遵循 Posix線程標準接口進行多線程程序編程,熟練掌握線程的創建 pthread_create(),線程的終止 pthread_exit(),等待線程合并 pthread_join()等線程控制操作,利用信號量或者互斥鎖實現線程建的同步。
二、實驗內容
問題:求 1000000 個浮點數(精確到小數點后 4 位)的平均值(和,最大值,最小值),具體的問題描述流程圖如下圖圖 1 所示:
三、實驗 步驟
1、隨機生成 1000000個浮點數; 2、創建 4個子線程,分別求 250000個浮點數之和; 3、完成 1000000 個浮點數之和并打印結果; 4、統計多線程并發執行完成計算的時間; 5、寫一個單線程程序,同樣完成 1000000 個隨機數求和的計算,統計計算時間,并和前面結果進行對比; 6、讓單線程程序睡眠四秒鐘、多線程程序各子程序睡一秒的條件下(兩個程序總的睡眠時間相同),對比執行結果; 7、分析兩次對比結果的差異,寫出自己的見解。
四、實驗結果與分析 1、單線程完成 1000000 個浮點數的求和運算所用的時間情況如下圖圖 2 所示:
圖 圖 2 單線程計算 時間
分析:實驗中每次隨機產生一個 0 到 1 之間的浮點數,1000000 個這樣的數相加的話的平總和大概就在 500000 左右(按照隨機數的平均值原理),實驗中 sum=,顯然結果正確,整個計算運行時間為。
2、單線程完成 1000000 個浮點數的求和運算,單線程中睡眠 4 秒鐘,所用的時間情況如下圖圖3 所示:
圖 圖 3 單線程計算 時間(睡眠 4 秒)分析:根據上一次單線程的執行情況來看,這一次讓單線程睡眠 4 秒鐘,最后執行時間剛好就是4 秒加上計算時間。也就是說計算 1000000 個浮點數的總和平均時間約為。
3、四個子線程共同完成 1000000 個浮點數的求和計算所用時間情況如下圖圖 4所示:
圖 圖 4 多線程計算時間
分析:因為這次是 4 個子線程并發運行,每個子線程只需計算 250000個浮點數的總和,理想情況下這時候的運行時間應該是這單線程中計算時間的四分之一。從圖中可以看到執行時間是,很顯然這個時間約為單線程求 1000000 個浮點數之和的時間()的四分之一,符合預期的結果。
4、四個子線程共同完成 1000000 個浮點數的求和計算,其中每個子線程睡眠 1 秒鐘,最終所用時間情況如下圖圖 5所示:
圖 圖 5 多線程計算時間(每個 子線程眠 睡眠 1 秒)
分析:這里四個子線程每個子線程睡眠一秒,但由于四個子線程并發同步的在執行,當一個子線程在睡眠時,另外一個子線程卻仍然在繼續求和計算,因此他們一起合作同步完成1000000個浮點數的計算所需的時間就是 1 秒加上上圖中不睡眠的時候的計算時間。從圖中可以
看到≈1s+,所以最終的結果符合預期值。
5、單線程計算時間(睡眠 4s)與多線程計算時間(每個子線程睡眠 1s)對比效果如下圖圖 6 所示:
圖 圖 6 單線程(睡眠 4s)與 與 多線程(每個眠 子線程睡眠 1s)計算時間 對比圖 五、程序源代碼 /************************* *FileName:
*Author:
*Date:2013/11/22 ***************************/ #include <> #include <> #include <> #include <> #include
int i;
srand(time(NULL));
for(i=0;i { SUM +=(float)(rand()/(float)RAND_MAX); } sleep(4);} int main(){ pthread_t p; int result; float time; struct timeval start; struct timeval end; gettimeofday(&start,NULL); result=pthread_create(&p,NULL,ADD,NULL); if(result!=0) { printf(“Create Thread of ADD Failuren”); exit(-1); } pthread_join(p,NULL); gettimeofday(&end,NULL); time =((float)-*1000000+(float) -)/1000000; printf(“Signal_Thread_Sum:%.4fn”,SUM); printf(“Signal_Thread_Execution_Time:%.4fs(sleep 4 sec)n”,time); return 0;} /************************* *FileName: *Author:wangtao *Date:2013/11/22 ***************************/ #include <> #include <> #include <> #include <> #include int i; srand(time(NULL)); for(i=0;i { pthread_mutex_lock(&mutex); SUM +=(float)((float)rand()/RAND_MAX); pthread_mutex_unlock(&mutex); } printf(“pthread%d:%.4fn”,*k,SUM); sleep(1);} int main(void){ pthread_t p1,p2,p3,p4; int result1,result2,result3,result4; int k1=1,k2=2,k3=3,k4=4; struct timeval start; struct timeval end; float time; gettimeofday(&start,NULL); pthread_mutex_init(&mutex,NULL); result1=pthread_create(&p1,NULL,(void*)ADD,&k1); result2=pthread_create(&p2,NULL,(void*)ADD,&k2); result3=pthread_create(&p3,NULL,(void*)ADD,&k3); result4=pthread_create(&p4,NULL,(void*)ADD,&k4); if(result1!=0||result2!=0||result3!=0||result4!=0) { printf(“Create Child Thread Failure!n”); exit(1); } pthread_join(p1,NULL); pthread_join(p2,NULL); pthread_join(p3,NULL); pthread_join(p4,NULL); gettimeofday(&end,NULL); time =((float)-*1000000 +(float)-)/1000000; printf(“SUM = %.4fn”,SUM); printf(“Multi_thread_time = %.4fs(Each child thread sleep 1 sec)n”,time); return 0;} 六、實驗體會 這是第一次使用多線程編程編寫代碼,第一次直觀感受到這種多線程編程對程序的執行速率的影響。雖然說操作系統課程已經上了好幾個星期了,課堂上一直在學習多線程編程的算法思想,但是那只是書面上的講授,真正直觀的感受和體會還是得依靠實驗來了解。 因為之前就接觸過 linux 系統,所以對于程序的編譯執行方面還是問題不大,最主要的就是代碼的編寫問題。一開始到實驗室完全不知道要做什么,因為根本連實驗內容都不知道,直到助教在大屏幕上顯示這個實驗題目,我才開始了解實驗的題目和要求。這里我就是想建議一下老師您可以應該給我們實驗題目,讓我們在實驗前就了解一下實驗內容,不然到了實驗室都不知道到底要干嘛。讀懂了解題意之后,我就開始參考所給的一些線程創建函數說明來編寫多線程同步完成1000000個浮點數的求和運算。因為對這些線程函數不是很了解,在使用 pthread_create()函數創建線程時,老是傳入函數參數不對,后來百度之后了解到傳入的子線程函數的類型應該為 void *(*start_thread)(void)形式。最后運行試驗與單線程的進行比較,強烈感受到多線程的并發同步運行的特點。 總之,這次試驗使我對課堂知識有了更深的體會和鞏固,為以后的課程學習打下了基礎。 許昌學院 《操作系統》實驗報告書 學號:姓名:閆金科班級:成績: 5006140057 14物聯網工程 2016年02月實驗一 Linux的安裝與配置 一、實驗目的 1.熟悉Linux系統的基本概念,比如Linux發行版、宏內核、微內核等。2.掌握Linux系統的安裝和配置過程,初步掌握Linux系統的啟動和退出方法。3.熟悉Linux系統的文件系統結構,了解Linux常用文件夾的作用。 二、實驗內容 1.從網絡上下載VMware軟件和兩個不同Linux發行版鏡像文件。2.安裝VMware虛擬機軟件。 3.在VMware中利用第一個鏡像文件完成第一個Linux的安裝,期間完成網絡信息、用戶信息、文件系統和硬盤分區等配置。 4.在VMware中利用第二個鏡像文件完成第二個Linux的安裝,并通過LILO或者GRUB解決兩個操作系統選擇啟動的問題。 5.啟動Linux系統,打開文件瀏覽器查看Linux系統的文件結構,并列舉出Linux常用目錄的作用。 三、實驗過程及結果 1、啟動VMware,點擊新建Linux虛擬機,如圖所示: 2、點擊下一步,選擇經典型,點擊下一步在選擇客戶機頁面選擇Linux,版本選擇Red Hat Enterprise Linux 5,如圖所示: 3、點擊下一步創建虛擬機名稱以及所要安裝的位置,如圖所示: 4、點擊下一步,磁盤容量填一個合適大小,此處選擇默認值大小10GB,如圖所示: 5、點擊完成,點擊編輯虛擬機設置,選擇硬件選項中的CD-ROM(IDE...)選項,在右側連接中選擇“使用ISO鏡像(I)”選項,點擊“瀏覽”,找到Linux的鏡像文件,如圖所示: 6點擊確定按鈕后,點擊啟動虛擬機按鈕,來到Linux的安裝界面,如圖所示: 7、到此頁面之后,等待自動檢測安裝,如圖所示: 8、等到出現如圖所示頁面后點擊“skip”按鈕,跳過檢測,直接進入安裝設置界面,如圖所示: 9、安裝設計界面如圖所示: 10、點擊Next按鈕進入設置語言界面,設置語言為“簡體中文”,如圖所示: 11、點擊Nest按鈕進入系統鍵盤設置按鈕,設置系統鍵盤為“美國英語式”,如圖所示: 12、點擊下一步按鈕,彈出“安裝號碼”對話框,選擇跳過輸入安裝號碼,如圖所示: 13、按照提示,一直點擊下一步按鈕,如圖所示: 14、到設置最后一步,點擊下一步按鈕進入開始安裝Red Hat Enterprise Linux Sever界面,如圖所示: 15、安裝完成后,進入歡迎界面,按照提示點擊前進按鈕知道進入Linux桌面,如圖所示: 16、安裝成功的Linux系統桌面如圖所示,桌面包含五個圖標,分別為:計算機、jk’s Home、回收站、RHEL/5.3 i386DVD。 四、實驗總結 通過安裝虛擬機等操作讓我認識到Linux這系統一些基本特點,本次試驗學會了安裝虛擬機并且使用虛擬機安裝操作系統,掌握了紅帽Linux系統的安裝和配置過程,以及對鏡像ISO文件的使用,有別于我們機器上使用的系統,通過虛擬機這個軟件還可以在已有系統的基礎上使用其他操作系統。安裝過程中一定要注意選擇版本的時候要選擇Red Hat Enterprise Linux 5版本,否則安裝不能成功。自己動手成功的安裝了Linux系統,自己對Linux的學習產生更大的興趣。 實驗二 Linux操作系統的運行模式 一、實驗目的 1.熟悉Linux系統終端工作環境的使用,了解Linux命令的格式,使用學會利用常用的Linux命令來完成系統的管理和維護。 2.了解X-Windows的特點,熟悉Linux圖形用戶接口的使用,掌握GNOME桌面環境的基本操作。 3.了解和掌握在Linux環境下安裝軟件包的方法,如QQ for Linux等用軟件的安裝方法。 二、實驗內容 1.啟動Linux系統打開虛擬終端界面,使用Linux的在線幫助指令man或help獲得ls、uname、date、cal、mkdir、cp等Linux命令的幫助手冊,了解這些命令的具體使用方法。同時,也可以通過執行“命令名 –help”來顯示該命令的幫助信息,如“ls –help”,試用這些命令。 2.通過uname命令的執行,查看并給出相關系統信息:操作系統的名稱、系統域名、系統CPU名稱等。 3.在主目錄下創建一個名為myetc的子目錄,將/etc目錄下與網絡相關的文件和子目錄拷貝到該目錄,并將這些文件的執行權限設置為可執行。 4.在主目錄/home下創建目錄program、music 和temp,然后在program下建立目錄java和C,列出完成該過程的所有命令。 5.在圖形界面環境中,查看GNOME桌面的面板和桌面,設置GNOME,包括屏幕保護程序、更改背景和指定關聯程序等。6.實現對光盤的加載和訪問,然后卸載。 三、實驗過程及結果 1、打開終端,輸入 【ls –help】來查看【ls】指令的使用方法,同理查看uname、date、cal、mkdir、cp的使用方法。 2、在終端中輸入【uname –a】顯示操作系統名系統cpu名和系統域名 3、重啟系統,用【root】用戶名進入系統,以獲得權限。在終端中輸入【mkdir myetc】,在主目錄下創建【myrtc】的目錄,【ls】查看是否創建。輸入【cd..】返回至【/】文件,輸入【cp –r etc root/myetc】講etc中內容復制到myetc中,進入myetc文件【ls】查看。輸入 【chmod u+x etc】賦予文件可執行的權限,輸入【ll】查看。 4、在home下,輸入【mkdir {program,music,temp}】,可在home下創立這三個目錄,輸入【ls】查看。在program下輸入【mkdir{java,C}】,可創立java和C兩個目錄,【ls】查看。 5、在桌面上方選擇【系統】-【首選項】,即可設置屏幕保護程序和更改背景和指定關聯程序 5、在桌面上可見看到有CD光盤,雙擊瀏覽,右鍵【彈出】即卸載。 四、實驗總結和體會 Linux的指令系統是學習Linux操作系統很重要的一部分,指令系統相當于在Windows操作系統下的doc,可以省去圖形化界面。通過這次的實驗讓我了解了Linux的強大功能,了解到Linux有許多方便快捷的設置基本配置的方法,這使我更喜歡上Linux的使用。在使用指令的過程中,有時候對文件的操作需要一定的權限,這時需要在登陸時用戶名使用【root】,而不是我們在安裝時使用的用戶名,這樣就獲得了管理員權限,可以對一些系統文件進行操作。 實驗三 Linux應用軟件與系統管理 一、實驗目的 1.了解OpenOffice.Org集成辦公軟件,掌握利用OpenOffice.Org的套件來完成文檔和圖片的處理。 2.了解Linux網絡管理的知識,熟悉Linux網絡配置的方法,掌握在Linux環境下配置Web服務器和ftp服務的方法。 二、實驗內容 1.配置Linux系統的網絡環境,安裝FTP和Web服務器,并配置相關的屬性,利用FTP實現WINDOWS和Linux之間的數據交換。 2.利用FTP程序上傳自己的照片到FTP服務器,利用OpenOffice的文字處理工具OpenOffice Writer制作一份表格形式的個人簡歷。個人簡歷中至少包含學號、姓名、性別、專業、照片和學習經歷等內容,并保存為網頁格式(html格式)。3.將個人簡歷網頁設置為WEB服務器的首頁,然后在客戶端利用瀏覽器訪問WEB服務器,查看效果。 4.通過讀取proc文件系統,獲取系統各種信息(如主機名、系統啟動時間、運行時間、版本號、所有進程信息、CPU使用率等),并以比較容易的方式顯示。 三、實驗過程及結果 1.配置網絡環境:在(服務.cmd).里面進行以下操作:在服務里選擇3按回車 完成后,可在本地連接看到VMware已連接上網絡 在虛擬機設置中設置以太網網絡連接方式為 網關地址填虛擬機的網管,IP地址設為虛擬機的一個子網: 四、總結: 在linux系統下,make是我們經常用到的編譯命令,所以關于make代碼和他的操作指令一定要記清楚。所以,熟練掌握了make和makefile工具之后,源碼安裝軟件就變的像windows下安裝軟件一樣簡單。 實驗四 進程控制與管理 一、實驗目的 1.掌握GCC編譯器的用法,學會利用GCC編輯器來編輯C語言程序,學會利用GDB調試器來調試C語言程序。 2.理解進程和程序的區別和聯系,3.掌握在Linux環境下觀察進程運行情況和CPU工作情況的命令。4.了解fork()系統調用,掌握利用fork()創建進程的方法。 5.了解Linux系統其他與進程相關的系統調用,如exec、wait和exit等。6.了解Linux常用的進程通信機制。 二、實驗內容 1.利用Linux的進程管理命令ps、top來監視和跟蹤進程,體會進程和程序的關系。2.利用Linux的文字編輯器編寫文件復制的C語言程序,并用gcc編譯該程序,然后運行該程序。 3.編寫一段程序,使用系統調用fork()創建兩個子進程。當此程序運行時,在系統中有一個父進程和兩個子進程活動。讓每一個進程在屏幕上顯示一個字符:父進程顯示'a',子進程分別顯示字符'b'和字符'c'。試觀察記錄屏幕上的顯示結果,并分析原因。 4.修改上述程序,每一個進程循環顯示一句話。子進程顯示'daughter ?'及'son ??',父進程顯示 'parent ??',觀察結果,分析原因。5.用fork()創建一個進程,再調用exec()用新的程序替換該子進程的內容。 三、實驗過程及結果 1、利用Linux的進程管理命令ps、top來監視和跟蹤進程,體會進程和程序的關系。<1>從用戶身份切換到ROOT身份 <2>輸入命令 ps 查看進程 <2>輸入命令 top 跟蹤進程 2、利用Linux的文字編輯器編寫一個計算機100個自然數和的C語言程序,并用gcc編譯該程序,然后運行該程序。 <1>創建一個.C文件 并進入進行編輯 <2>用GCC 進行編譯,再查看文件,發現產生執行文件 a.out <3>執行這個可執行文件得到結果5050 1、編寫一段程序,使用系統調用fork()創建兩個子進程。當此程序運行時,在系統中有一個父進程和兩個子進程活動。讓每一個進程在屏幕上顯示一個字符:父進程顯示'a',子進程分別顯示字符'b'和字符'c'。試觀察記錄屏幕上的顯示結果,并分析原因。 <1>穿件一個.C文件 并進行編寫程序代碼 <2>反復執行2次該程序 <3>可以看出兩次執行的結果 a b c 出現的順序不同,原因是,3個進程的輸出次序是隨機的,并不會按規定的順序出現,所以會出現上述結果。 4、修改上述程序,每一個進程循環顯示一句話。子進程顯示'daughter ?'及'son ??',父進程顯示 'parent ??',觀察結果,分析原因。<1>重新修改代碼 <3>執行這段程序 <4>原分析: 因和之前一樣,可以看出執行的結果 3個單詞出現的順序不同,原因是,3個進程的輸出次序是隨機的,并不會按規定的順序出現,所以會出現上述結果。 5、用fork()創建一個進程,再調用exec()用新的程序替換該子進程的內容。<1> 編寫代碼 <2> 執行的結果 結果表明 execl 替代了son的內容 四、實驗總結和體會 這個實驗考察的是進程之間存在很多可能性以及對編輯器的使用。本次實驗學習了在linux環境下用gcc編譯器運行c語言程序,在linux環境下編寫程序用到了vi編輯器,知道了該編輯器也需要各種命令來操作。編寫C語言程序時用到了fork()函數,再調用execl()用新的程序替換該子進程的內容。 實驗五 進程調度模擬程序的設計與實現 一、實驗目的 1.了解進程調度的概念,掌握常用進程調度算法的原理。2.掌握Linux程序設計編輯、編譯和調試的技巧。 二、實驗內容 1.編寫程序實現進程調度調度算法先來先服務、優先級高優先和時間片輪轉調度算法。(編程語言不限) 2.輸入數據,輸出運行結果。 三、實驗過程及結果 1先來先服務 #i nclude struct { int id; float ArriveTime;float RequestTime;float StartTime;float EndTime;float RunTime;float DQRunTime;int Status;}arrayTask[4];GetTask(){ int i;float a; for(i=0;i<4;i++){arrayTask[i].id=i+1;printf(“input the number”); printf(“input the the ArriveTime of arrayTask[%d]:”,i);scanf(“%f”,&a); arrayTask[i].ArriveTime=a; printf(“input the RequestTime of arrayTask[%d]:”,i);scanf(“%f”,&a); arrayTask[i].RequestTime=a;arrayTask[i].StartTime=0;arrayTask[i].EndTime=0;arrayTask[i].RunTime=0;arrayTask[i].Status=0; } } int fcfs() { int i,j,w=0; for(i=0;i<4;i++) { if(arrayTask[i].Status==0) { t=arrayTask[i].ArriveTime; w=1; } if(w==1) break; } for(i=0;i<4;i++) { if(arrayTask[i].ArriveTime t=arrayTask[i].ArriveTime; } for(i=0;i<4;i++) { if(arrayTask[i].ArriveTime==t) return i; } } int sjf(){ int i,x=0,a=0,b=0;float g; for(i=0;i<4;i++){ if(arrayTask[i].Status==1){g=arrayTask[i].EndTime;x=1;} } if(x==0){ t=arrayTask[0].ArriveTime; for(i=0;i<4;i++){ if(arrayTask[i].ArriveTime t=arrayTask[i].ArriveTime;a=i;} } return a;} else { for(i=0;i<4;i++){ if(arrayTask[i].EndTime>g)g=arrayTask[i].EndTime;} for(i=0;i<4;i++){ if(arrayTask[i].Status==0&& arrayTask[i].ArriveTime<=g){ t=arrayTask[i].RequestTime;a=i;b=1;} /*判斷有沒有進程在前個進程完成前到達*/ } if(b!=0)/*有進程到達則按SJF*/ { for(i=0;i<4;i++){ if(arrayTask[i].Status==0&&arrayTask[i].ArriveTime<=g&&arrayTask[i].RequestTime return a;} else{ /*否則按FCFS*/ for(i=0;i<4;i++) {if(arrayTask[i].Status==0)t=arrayTask[i].ArriveTime;} for(i=0;i<4;i++){ if(arrayTask[i].Status==0&&arrayTask[i].ArriveTime return a;} } } new(int s)/*定義執行進程后相關數據的修改*/ { int i,g=0;for(i=0;i<4;i++){ if(arrayTask[i].Status==0)continue;else { g=1;break;} } if(g==0)/*當處理的是第一個未執行的進程時執行*/ { arrayTask[s].StartTime=arrayTask[s].ArriveTime; arrayTask[s].EndTime=arrayTask[s].RequestTime+arrayTask[s].ArriveTime;arrayTask[s].RunTime=arrayTask[s].RequestTime;arrayTask[s].Status=1;g=2;} if(g==1)/*當處理的不是第一個未執行的進程時執行*/ { arrayTask[s].Status=1;for(i=0;i<4;i++){ if(arrayTask[i].Status==1)d=arrayTask[i].EndTime;} for(i=0;i<4;i++)/*查找最后執行的進程的完成時間*/ { if(arrayTask[i].EndTime>d&&arrayTask[i].Status==1)d=arrayTask[i].EndTime;} if(arrayTask[s].ArriveTime arrayTask[s].StartTime=arrayTask[s].ArriveTime; arrayTask[s].EndTime=arrayTask[s].StartTime+arrayTask[s].RequestTime;arrayTask[s].RunTime=arrayTask[s].EndTime-arrayTask[s].ArriveTime;} arrayTask[s].DQRunTime=arrayTask[s].RunTime/arrayTask[s].RequestTime;} Printresult(int j)/*定義打印函數*/ { printf(“%dt”,arrayTask[j].id); printf(“%5.2ft”,arrayTask[j].ArriveTime);printf(“%5.2ft”,arrayTask[j].RequestTime);printf(“%5.2ft”,arrayTask[j].StartTime);printf(“%5.2ft”,arrayTask[j].EndTime);printf(“%5.2ft”,arrayTask[j].RunTime);printf(“%5.2fn”,arrayTask[j].DQRunTime);} main(){ int i,b,k,a,c=0;int d[4];clrscr(); printf(“t F.FCFS n”);printf(“t S.SFJ n”);printf(“t Q.EXIT n”);for(i=0;;i++){ if(c)break; printf(“please input the number a:n”);scanf(“%d”,&a);switch(a){ case Q: c=1;break; case F:printf(“please input the different-ArriveTime of arrayTasksn”);GetTask(); printf(“*****************************the result of fcfsn”);printf(“NumbertArrivetServertStarttFinishtTurnovetTake power turnover timen”); for(b=0;b<4;b++)/*調用兩個函數改變結構體數的值*/ { k=fcfs();d[b]=k;new(k);} for(b=0;b<4;b++) Printresult(d[b]);/*調用打印函數打出結果*/ continue; case S: printf(“please input the different-RequestTime of array Tasksn”);GetTask(); printf(“******************************the result of sjfn”);printf(“NumbertArrivetRequesttStarttEndtRuntDQRun timen”);for(b=0;b<4;b++){ k=sjf();d[b]=k;new(k);} for(b=0;b<4;b++)Printresult(d[b]);continue; default:printf(“the number Error.please input another number!n”);} } } 四、實驗總結和體會 通過做本實驗,讓我對進程或作業先來先服務、高優先權、按時間片輪轉調度算法以及進程調度的概念和算法,有了更深入的認識!理解進程的狀態及變化,動態顯示每個進程的當前狀態及進程的調度情況。進程調度是處理機管理的核心內容。優先級高優先是根據作業的優先級,總是選擇優先級最高者進入隊列。輪轉調度算法是調度程序每次把CPU分配給就緒隊列首進程/線程使用規定的時間間隔,就緒隊列中都路保留巡行一個時間片。 實驗二 進程調度 1.目的和要求 通過這次實驗,理解進程調度的過程,進一步掌握進程狀態的轉變、進程調度的策略,進一步體會多道程序并發執行的特點,并分析具體的調度算法的特點,掌握對系統性能的評價方法。 2.實驗內容 閱讀教材《計算機操作系統》第二章和第三章,掌握進程管理及調度相關概念和原理。 編寫程序模擬實現進程的輪轉法調度過程,模擬程序只對PCB進行相應的調度模擬操作,不需要實際程序。假設初始狀態為:有n個進程處于就緒狀態,有m個進程處于阻塞狀態。采用輪轉法進程調度算法進行調度(調度過程中,假設處于執行狀態的進程不會阻塞),且每過t個時間片系統釋放資源,喚醒處于阻塞隊列隊首的進程。 程序要求如下: 1)輸出系統中進程的調度次序; 2)計算CPU利用率。 3.實驗環境 Windows操作系統、VC++6.0 C語言 4設計思想: (1) 程序中進程可用PCB表示,其類型描述如下: struct PCB_type { int pid; //進程名 int state; //進程狀態 2——表示“執行”狀態 1——表示“就緒”狀態 0——表示“阻塞”狀態 int cpu_time;//運行需要的CPU時間(需運行的時間片個數) } 用PCB來模擬進程; (2)設置兩個隊列,將處于“就緒”狀態的進程PCB掛在隊列ready中;將處于“阻塞”狀態的進程PCB掛在隊列blocked中。隊列類型描述如下: struct QueueNode{ struct PCB_type PCB; Struct QueueNode *next;} 并設全程量: struct QueueNode *ready_head=NULL,//ready隊列隊首指針 *ready_tail=NULL , //ready隊列隊尾指針 *blocked_head=NULL,//blocked隊列隊首指針 *blocked_tail=NULL;//blocked隊列隊尾指針(3)設計子程序: start_state(); 讀入假設的數據,設置系統初始狀態,即初始化就緒隊列和阻塞隊列。 dispath(); 模擬調度,當就緒隊列的隊首進程運行一個時間片后,放到就緒隊列末尾,每次都是隊首進程進行調度,一個進程運行結束就從就緒隊列中刪除,當到t個時間片后,喚醒阻塞隊列隊首進程。 calculate(); 就緒進程運行一次,usecpu加1,當就緒隊列為空時unusecpu加1,CPU利用率為use_cpu/(use_cpu+unuse_cpu)。 5源代碼: #include struct PCB_type { int pid; //進程名 int state; //進程狀態 //2--表示“執行”狀態 //1--表示“就緒”狀態 //0--表示“阻塞”狀態 int cpu_time;//運行需要的CPU時間(需運行的時間片個數)};struct QueueNode{ struct PCB_type PCB; struct QueueNode *next;};struct QueueNode *ready_head=NULL,//ready隊列隊首指針 *ready_tail=NULL,//ready隊列隊尾指針 *block_head=NULL,//blocked隊列隊首指針 *block_tail=NULL; //blocked隊列隊尾指針 int use_cpu,unuse_cpu; void start_state()//讀入假設的數據,設置系統初始狀態 { int n,m; int i; struct QueueNode *p,*q; printf(“輸入就緒節點個數n:”); scanf(“%d”,&n); printf(“輸入阻塞節點個數m:”); scanf(“%d”,&m); p=(struct QueueNode *)malloc(sizeof(struct QueueNode)); p->next =NULL; ready_head=ready_tail=p; for(i=0;i { p=(struct QueueNode *)malloc(sizeof(struct QueueNode)); p->next =NULL; p->PCB.state=1; printf(“輸入就緒進程%d的pid和cpu_time:”,i+1); scanf(“%d%d”,&p->PCB.pid,&p->PCB.cpu_time); ready_tail->next=p; ready_tail=p; } q=(struct QueueNode *)malloc(sizeof(struct QueueNode)); q->next =NULL; block_head=block_tail=q; for(i=0;i { q=(struct QueueNode *)malloc(sizeof(struct QueueNode)); q->next=NULL; q->PCB.state=0; printf(“輸入阻塞進程%d的pid和cpu_time:”,i+1); scanf(“%d%d”,&q->PCB.pid,&q->PCB.cpu_time); block_tail->next=q; block_tail=q; } printf(“n處于就緒狀態的進程有:n”); p=ready_head->next; i=1; while(p) {printf(“進程%d的pid和cpu_time:%5d%5d%5dn“,i,p->PCB.pid,p->PCB.state,p->PCB.cpu_time); p=p->next; i++; } } void dispath() //模擬調度 { int x=0,t; use_cpu=0; unuse_cpu=0; printf(”輸入t:“); scanf(”%d“,&t); printf(”開始調度n“); while(ready_head!=ready_tail||block_head!=block_tail) { struct QueueNode *p,*q; if(ready_head!=ready_tail) { p=ready_head->next; ready_head->next=p->next; p->next=NULL; if(ready_head->next==NULL) { ready_tail=ready_head; } p->PCB.state=2; printf(”進程%d調度t“,p->PCB.pid); state和 use_cpu++; x++; p->PCB.cpu_time--; if(p->PCB.cpu_time) { ready_tail->next=p; ready_tail=p; } else { printf(”進程%d完成t“,p->PCB.pid); free(p); } } else { unuse_cpu++; x++; printf(”空閑一個時間片t“); } if(x==t&&block_head!=block_tail) { q=block_head->next; block_head->next=q->next; q->next=NULL; if(block_head->next==NULL) { block_tail=block_head; } ready_tail->next=q; ready_tail=q; x=0; } } } void calculate() //計算CPU利用率 { printf(”ncpu的利用率%.2fn“,(float)use_cpu/(use_cpu+unuse_cpu)); } void main(){start_state(); dispath(); calculate();} 6運行結果: 7實驗總結: 實驗幫我復習了數據結構和C語言,且鞏固課本知識,知道了如何定義結構體,如何在鏈接隊列中增刪節點。模擬進程調度幫我們鞏固了進程三狀態之間的變遷。懂得調式的重要性。總之,我們明白了理論聯系實際。多看書,多上機。 實驗三 可變分區存儲管理 1.目的和要求 通過這次實驗,加深對內存管理的認識,進一步掌握內存的分配、回收算法的思想。 2.實驗內容 閱讀教材《計算機操作系統》第四章,掌握存儲器管理相關概念和原理。編寫程序模擬實現內存的動態分區法存儲管理。內存空閑區使用自由鏈管理,采用最壞適應算法從自由鏈中尋找空閑區進行分配,內存回收時假定不做與相鄰空閑區的合并。 假定系統的內存共640K,初始狀態為操作系統本身占用64K。在t1時間之后,有作業A、B、C、D分別請求8K、16K、64K、124K的內存空間;在t2時間之后,作業C完成;在t3時間之后,作業E請求50K的內存空間;在t4時間之后,作業D完成。要求編程序分別輸出t1、t2、t3、t4時刻內存的空閑區的狀態。 3.實驗環境 Windows操作系統、VC++6.0 C語言 4.設計思想 模擬內存分配和回收,要設置兩個鏈隊列,一個空閑區鏈和一個占用區鏈,空閑區鏈節點有起始地址,大小和指向下一節點的指針等數據域,占用區鏈節點有起始地址,大小,作業名和指向下一節點的指針等數據域,本實驗用最壞適應算法,每次作業申請內存都是從空閑鏈隊頭節點分配,如果相等,就刪除空閑頭結點,如果小于申請的,就不分配,否則就劃分內存給作業,剩下的內存大小,重新插入空閑鏈隊,按從大到小,接著把作業占用的內存放到占用區鏈節點的末尾。每次作業運行完,就要回收其占用的內存大小,把作業節點按從大到小插入到空閑鏈隊中。5.源代碼: #include struct freelinkNode *next;};struct busylinkNode{ char name; int len;int address;struct busylinkNode *next;};struct freelinkNode *free_head=NULL; //自由鏈隊列(帶頭結點)隊首指針 struct busylinkNode *busy_head=NULL; //占用區隊列隊(帶頭結點)首指針 struct busylinkNode *busy_tail=NULL; //占用區隊列隊尾指針 void start(void)/* 設置系統初始狀態*/ { struct freelinkNode *p; struct busylinkNode *q; free_head=(struct freelinkNode*)malloc(sizeof(struct freelinkNode)); free_head->next=NULL;// 創建自由鏈頭結點 busy_head=busy_tail=(struct busylinkNode*)malloc(sizeof(struct busylinkNode)); busy_head->next=NULL;// 創建占用鏈頭結點 p=(struct freelinkNode *)malloc(sizeof(struct freelinkNode)); p->address=64; p->len=640-64;//OS占用了64K p->next=NULL; free_head->next=p; q=(struct busylinkNode *)malloc(sizeof(struct busylinkNode)); q->name='S';/* S表示操作系統占用 */ q->len=64;q->address=0;q->next=NULL; busy_head->next=q;busy_tail=q;} void requireMemo(char name, int require)/*模擬內存分配*/ { freelinkNode *w,*u,*v;busylinkNode *p;if(free_head->next->len>=require){ p=(struct busylinkNode*)malloc(sizeof(struct busylinkNode)); p->name=name; p->address=free_head->next->address; p->len=require; p->next=NULL; busy_tail->next=p; busy_tail=p;} else printf(”Can't allocate“); w=free_head->next; free_head->next=w->next; if(w->len==require) { free(w);} else { w->address=w->address+require; w->len=w->len-require;} u=free_head; v=free_head->next; while((v!=NULL)&&(v->len>w->len)){ u=v; v=v->next;} u->next=w; w->next=v;} void freeMemo(char name)/* 模擬內存回收*/ { int len; int address;busylinkNode *q,*p;freelinkNode *w,*u,*v;q=busy_head; p=busy_head->next; while((p!=NULL)&&(p->name!=name)) { q=p; p=p->next;} if(p==NULL){ printf(”%c is not exist“,name);} else { if(p==busy_tail) { busy_tail=q; } else { q->next=p->next; len=p->len; address=p->address; free(p); w=(struct freelinkNode*)malloc(sizeof(struct freelinkNode)); w->len=len; w->address=address; u=free_head; v=free_head->next; while((v!=NULL)&&(v->len>len)) { u=v;v=v->next; } u->next=w; w->next=v; } } } void past(int time)/* 模擬系統過了time 時間*/ { printf(”過了時間%d后:n“,time);} void printlink()/* 輸出內存空閑情況(自由鏈的結點)*/ { freelinkNode *p; printf(”內存的空閑情況為:n“); p=(struct freelinkNode *)malloc(sizeof(struct freelinkNode)); p=free_head->next; while(p!=NULL) { printf(”內存的起始地址和內存的大小%5dt%5d:n",p->address,p->len); p=p->next; } } void main(){ int t1=1,t2=2,t3=3,t4=4; start(); past(t1); requireMemo('A',8); requireMemo('B',16); requireMemo('C',64); requireMemo('D',124); printlink(); past(t2); freeMemo('C'); printlink(); past(t3); requireMemo('E',50); printlink(); past(t4); freeMemo('D'); printlink();} 6.運行結果: 7.實驗總結: 鞏固編程能力,和調式能力,復習課本知識,明白理論聯系實際的重要性,動手能力非常重要,多看書,多獨立思考,品味痛苦的過程,享受成功的喜悅。 操作系統實驗報告 院系:數計學院 班級:大類6班 學號:100511624 姓名:明章輝 指導教師:徐軍利 實驗報告一 一、實驗目的 通過本實驗,掌握Linux的基本操作以及Linux的文本編輯,對Linux有一個基本的了解。 二、實驗任務 1、Linux的基本操作 1)在圖形交互方式下實現對用戶、用戶組和文件的管理。要求使用圖形交互界面添加一個用戶“mary”(密碼1234)和一個用戶組“dancer”,并將用戶Mary添加到dancer組中,最后在Mary目錄下建立一個名為test1的文件。 2)在命令方式下實現對用戶、用戶組和文件的管理。要求在命令交互方式下完成添加一個用戶(以自己的名字命名),并以此用戶名登錄。3)用Vi編輯器建立一個名為test2的文件,并輸入指定內容。 2、掌握Vi文本編輯器的使用 使用Vi編輯器建立、編輯、顯示以及加工處理文本文件。1)進入和退出vi。 2)利用文本插入方式建立一個文件test2。輸入以下內容: To the only woman that I love, For many years you have been my wife We've been through much together I love you dearly with my life and could not have picked much better.3)在新建的文本文件上移動光標。 4)對文本文件執行刪除、復原、修改等操作。 三、實驗設備 VMware虛擬機下的Linux操作系統 四、實驗步驟 1、Linux的基本操作 第一步:添加用戶: 點擊“草帽”圖標->“系統設置”->“用戶和組群”,出現“用戶管理器”界面,單擊“添加用戶”按鈕,在彈出的“創建新用戶”界面中創建用戶,用戶名為“mary”密碼為“123456” 第二步:添加用戶組: 單擊“添加組群”按鈕,在彈出的“創建新組群”對話框中新建組,組名為“dancer” 第三步:將用戶添加到組: 選中“mary”,點擊“屬性”按鈕或者是雙擊,選擇“組群”,然后將該用戶加入“dancer”中,單擊“確定”按鈕即可。 第四步:在圖形界面下創建和編輯文件 單擊草帽圖標,選擇附件中的文本編輯器。命名為“test1”,保存在“mary”所在的文件夾里 2、在命令方式下實現對用戶、用戶組和文件的管理。第一步:進入命令行界面 桌面上單擊鼠標右鍵,選擇“新建終端”,出現終端窗口和命令行提示符# 第二步:添加用戶,使用Useradd命令,格式為:useraddwangshumin 第三步:修改密碼,使用passwd命令,格式為:passwdwangshumin 第四步:注銷賬號,以新建的用戶名登陸 實驗截圖如下: 3、Vi編輯器的使用 第一步、在命令行界面系統提示符下輸入命令:vi test2,然后按〈Enter〉,建立新文件test2,并進入文件test2的文本編輯狀態 第二步、命令方式下用i命令,輸入所要求輸入的文本內容 第三步、在vi編輯器下練習刪除、瀏覽、復原等操作 第四步使用more命令查看文件內容,格式為:more test2 實驗截圖如下: 五、實驗問題及解決方法 1、在添加用戶時,密碼輸入四位提示錯誤,輸入六位以上即可 2、新建用戶名時組名錯誤,想刪除卻刪除不了,重命名之后提示用戶已存在,暫時還沒解決 3、由于不是很熟悉操作,發生了很多不必要的小錯誤,經摸索了解了許多。 六、實驗心得體會 通過此次試驗,由剛開始對實驗的不了解到基本了解了實驗內容,剛開始不熟悉操作,中途鬧出很多笑話,通過組員間的相互幫助,問題很快便迎刃而解,進一步理解了合作的重要性。同時也對linux系統產生了興趣,掌握到雙系統的相關知識。另外,針對這個專業,多動手多實踐才是最重要,這一次實驗下來收獲頗多,也認識到自身所存在的不足,今后會多一份努力,多一份實踐。 Linux實驗報告一 一、實驗步驟及內容 1.虛擬機軟件的安裝 (1)先準備虛擬機安裝包。 (2)更改安裝路徑: “D: VMwareVMware Workstationvmware.exe” (3)輸入序列號:ctrl+v,在安裝過程中不能進行復制剪切操作。 (4)不能重新啟動,才能繼續安裝漢化版D: vmwarevmware workstation 2.新建一個虛擬機并進行配置 (1)單擊新建虛擬機虛擬機的類型選擇:典型安裝 選擇客戶端操作系統 :linux虛擬機的名字及位置根據需要網絡類型選擇:,橋接。指定的磁盤容量刪除軟驅:雙擊 floppy—remove虛擬內存設置:雙擊memory—1024MB設置linux的安裝文件:選擇安裝鏡像文件—指定第一個安裝文件—就可以啦!之后會提示安裝第二個安裝文件 就進行選擇第二個 中間鼠標切換用CTRL+ALT。 3.安裝LINUX操作系統 (1)要確定鼠標是否在虛擬機的激活狀態下:敲回車不需要檢測安裝文件選擇 skip進入linux的安裝前的配置選項:選擇安裝的語言—中文簡體鍵盤:--默認鼠標:--默認安裝類型:--workstation磁盤分區:--自動分區引導程序:默認網絡配置:默認防火墻:無防火墻支持的語言:中文時區:亞洲-上海密碼:root123456安裝的軟件包:全部。 二 .在已有虛擬機軟件的基礎上安裝LINUX的技巧。 (1)新建虛擬機—典型安裝—linux ,red hat linux---給虛擬機命名,并且指定安裝位置d:red hat linux---橋接---10G。 (2)在剛才建立的虛擬機上安裝linux系統.(3)配置要安裝的linux系統的安裝文件iso鏡像文件 (4)選擇配置好linux鏡像文件剛才建立的虛擬機,啟動虛擬機,開始安裝。 三 .實驗總結 充分了解linux系統的安裝,學會新建虛擬機,在虛擬機上安裝linux系統.和一些簡單的技巧并對此門課程有了一定的興趣。第二篇:操作系統實驗報告
第三篇:操作系統實驗報告
第四篇:操作系統實驗報告一
第五篇:linux操作系統實驗報告