西安交大操作系統(tǒng)課內(nèi)實驗指導(dǎo)書_第1頁
西安交大操作系統(tǒng)課內(nèi)實驗指導(dǎo)書_第2頁
西安交大操作系統(tǒng)課內(nèi)實驗指導(dǎo)書_第3頁
西安交大操作系統(tǒng)課內(nèi)實驗指導(dǎo)書_第4頁
西安交大操作系統(tǒng)課內(nèi)實驗指導(dǎo)書_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、個人資料整理 僅限學(xué)習(xí)使用操作系統(tǒng)原理課內(nèi)實驗指導(dǎo)書實驗一:用戶接口實驗準備知識注意:內(nèi)核編譯和系統(tǒng)調(diào)用添加部分請參考共享的其他相關(guān)資料,實驗指導(dǎo)書的內(nèi)容多有錯謬之處。亦可自行網(wǎng)上搜索相關(guān)教程。b5E2RGbCAP為了使用戶通過操作系統(tǒng)完成各項管理任務(wù),操作系統(tǒng)必須為用戶提供各種接口來實現(xiàn)人 機交互。經(jīng)典的操作系統(tǒng)理論將操作系統(tǒng)的接口分為控制臺命令和系統(tǒng)調(diào)用兩種。前者主 要提供給計算機的操作人員對計算機進行各種控制;而后者則提供個程序員,使他們可以 方便地使用計算機的各種資源。 plEanqFDPw1.控制臺命令接口操作系統(tǒng)向用戶提供一組控制臺命令,用戶可以通過終端輸入命令的方式獲得操作系 統(tǒng)

2、的服務(wù),并由此來控制自己作業(yè)的運行。一般來講,控制臺命令應(yīng)該包含:一組命令、 終端處理程序以及命令解釋程序。DXDiTa9E3d1) bash的由來當?shù)卿汱inux或者打開一個 xterm時,當前默認的 shell就是bash。Bash是GNU Project的 shell。GNU Project 是自由軟件基金會 <Free Software Foundation)的一部分。它對 Linux 下 的許多編程工具負責(zé)。 Bash<Bourne Again Shell)是自由軟件基金會發(fā)布的 Bourne shell的 兼容程序。它包含了其他有些 shell的許多良好的特性,功能非常

3、的全面。很多 Linux版本 都供 bash。RTCrpUDGiT2) bash的大致原理bash處理自己的腳本時,先找到需要處理的命令名稱,進而在當前用戶的默認命令目錄中找到對應(yīng)的命令,這些默認目錄一般是/usr/bin、/bin或/sbin。在執(zhí)行這些命令時,先使用進程創(chuàng)建系統(tǒng)調(diào)用fork< ),在使用exex<)來執(zhí)行這些命令。5PCzVD7HxA3)建立bash腳本編輯文件可以用最熟悉的編輯器來編輯這個文本文件,比如文件名為script,在shell下輸入:$ vi script進入vi編輯器,在編輯器中輸入以下內(nèi)容#!/bin/bashecho Hello World!然

4、后保存,退出。測試腳本。使用指令:$source script更改腳本屬性使用指令:$chmod a+x script將腳本程序設(shè)置為可執(zhí)行。執(zhí)行腳本使用指令:$./script4)關(guān)鍵字參考echo在終端上顯示bash特殊變量19,保存當前進程或腳本的前9個參數(shù)。ls列舉目錄wc統(tǒng)計數(shù)量function定義函數(shù)2.系統(tǒng)調(diào)用系統(tǒng)調(diào)用是操作系統(tǒng)為程序員提供的接口服務(wù)。使用系統(tǒng)調(diào)用,程序員可以更充分的利用 計算機資源,使編寫的程序更加靈活,功能更加強大。程序員在對系統(tǒng)充分了解的情況下甚至可以訂做系統(tǒng)調(diào)用,實現(xiàn)那些非專業(yè)程序員所難以實現(xiàn)的功能。jLBHrnAILg1)添加源代碼第一個任務(wù)是編寫添加到

5、內(nèi)核的源程序,即添加到內(nèi)核文件中的一個函數(shù)。該函數(shù)的名稱應(yīng)該是在新的系統(tǒng)調(diào)用名稱之間前加上sys_標志。假設(shè)新加的系統(tǒng)調(diào)用為foo<),功能為原值返回輸入的整型數(shù)。格式為int foo<int iNumber ),返回的值就是出入的參數(shù)。在/usr/src/linux/kernel/sys.c 文件中添加源代碼,如下所示:xHAQX74J0Xasmlinkage int sys_foo<int x ) printf<n%cdx。注意:目錄“/usr/src/linux是linux各個版本的統(tǒng)稱,它因系統(tǒng)內(nèi)核的版本不同而名稱 不同。例如,當前操作系統(tǒng)是Linux7.1器內(nèi)

6、核四Linux-2.4.2,所以在“usr/src目'錄下有兩個文件:Linux-2.4和Linux-2.4.2,其中Linux-2.4是Linux-2.4.2的連接文件,程序員可以進入 任何一個目錄,它對內(nèi)核的修改都是一樣的。LDAYtRyKfE2)連接新的系統(tǒng)調(diào)用添加新的系統(tǒng)調(diào)用之后,下一個任務(wù)是讓Linux內(nèi)核的其余部分知道該程序的存在。為了從已有的內(nèi)核程序中增加新函數(shù)的鏈接,需要進行下面的操作:Zzz6ZB2Ltk(1) 進入目錄/usr/src/linux/include/asm-i386/ ,打開文件 unistd.h。這個文件包含了系統(tǒng)調(diào)用的清單,用來給每個系統(tǒng)調(diào)用分配一

7、個唯一的號碼。dvzfvkwMII系統(tǒng)調(diào)用號的定義格式如下:#define NR name NNN其中,name以系統(tǒng)調(diào)用名稱代替,而 NNN是該系統(tǒng)調(diào)用對應(yīng)的號碼,應(yīng)該將新的 系統(tǒng)調(diào)用名稱放到清單的最后,并給它分配已經(jīng)用到的系統(tǒng)調(diào)用號后面的一個號碼,比 如:rqyn14ZNXI#define _NR_foo 222以上的系統(tǒng)調(diào)用號便是 222。Linux內(nèi)核自身用的系統(tǒng)調(diào)用號已經(jīng)用到了221 了。如果讀者還要自行增加系統(tǒng)調(diào)用,就必須從223開始。EmxvxOtOco進入/usr/src/linux/arche/ i386/kernel/,打開文件 entry.S。該文件中有類似下面的清 單:

8、SixE2yXPq5ENTRY<sys_call_table ).long SYSMBOL_NAME(sys_ni_syscall>.long SYSMBOL_NAME(sys_exitl>.long SYSMBOL_NAME(sys_fork>在該表的最后加上:.long SYSMBOL_NAME(sys_foo>3)重新編譯內(nèi)核為了使新的系統(tǒng)調(diào)用生效,需要重建Linux的內(nèi)核,首先必須以 root的身份登錄。進入目錄:/usr/src/linux/ ,重建內(nèi)核:6ewMyirQFLrootlinuxserver root#make menuconfig / 配

9、置新內(nèi)核rootlinuxserver root#make dep / 創(chuàng)建新內(nèi)核rootlinuxserver root#make moduless install / 加入模塊 kavU42VRUsrootlinuxserver root#make clean / 清楚多余創(chuàng)建的文件rootlinuxserver root#make bzImage / 生成可執(zhí)行內(nèi)核引導(dǎo)文件4)使用新編譯的內(nèi)核cp -a /usr/src/linux-2.4.2/arch/i386/boot/bzImage/boot y6V3AL0s895) 重新配置/etc/lilo.conf文件使用vi編輯器編輯/e

10、tc/lilo.conf文件:vi /etc/lilo.conf在其中加入如下幾行:Image=/boot/bzImage#啟動內(nèi)核的位置,即自己#新配置的內(nèi)核所在目錄label = xhlinux #給內(nèi)核起一個名稱,配#置完成,重新啟動的時候,#會顯示這個名稱read_only#定義新的內(nèi)核為只讀root=/dev/hda5#定義硬盤的啟動位置為#/dev/hda5,在該設(shè)計中沒有變#仿照以前內(nèi)核引導(dǎo)位置,不#用修改,用以前的就可以了6)重啟系統(tǒng)完成以上配置后,重新啟動系統(tǒng)進入自己的新系統(tǒng)實驗指導(dǎo)1.控制臺命令接口實驗指導(dǎo)1)查看bash版本在shell提示符下輸入:$echo $BASH

11、_VERSION2)編寫bash腳本:統(tǒng)計/my目錄下c語言文件的個數(shù)通過bash腳本,可以有多種方式實現(xiàn)這個功能,而使用函數(shù)是其中個一個選擇。在使用函數(shù)之前,必須先定義函數(shù)。M2ub6vSTnP<1)進入自己的工作目錄,用vi編寫名為count的文件cd /home/student #在 home/student 目錄下編程vi count下面是腳本程序:#! /bin/bashfunction countecho -n " Number of matches for $1: "# 接收程序的第一個參數(shù) 0YujCfmUCws $1|wc -4 #對子程序的第一個參

12、數(shù)所在的目錄進行操作<2)執(zhí)行將count文件復(fù)制到當前目錄下,然后在當前目錄下建立文件夾my:mkdir my3) cd myvi 1.c # 在my目錄下建立幾個 c文件,以便用來進行測試 cd .chmod +x count./count './my/*.c '單引號)2.系統(tǒng)調(diào)用實驗指導(dǎo)1) 編程調(diào)用一個系統(tǒng)調(diào)用fork<)在應(yīng)用程序中調(diào)用系統(tǒng)調(diào)用fork< )非常簡單,下面的程序可以很清楚的顯示出有fork< )系統(tǒng)調(diào)用生成了子進程,而產(chǎn)生的分叉作用:eUts8ZQVRd# include <stdio.h>int main(>

13、;int iUid 。iUid=fork(> if(iUid=0>for(。> printf("This is parent.n">。sleep(1>。if(iUid>0>for(。> printf("This is child.n">。sleep(1> 。if(iUid<0> printf("Can not use system call.n">。return 0 。下面是可能得到的一種結(jié)果:this is child.this is parent.thi

14、s is child.this is parent.this is parent.this is child.this is child.this is parent.this is parent.this is child.this is child.this is parent.this is parent. this is child.2)編程調(diào)用創(chuàng)建的系統(tǒng)調(diào)用foo<)foo<)是本實驗系統(tǒng)設(shè)計者自行添加的一個簡單的系統(tǒng)調(diào)用。其實現(xiàn)過程在前面一進介紹了,它的功能很簡單,就是向標準輸出一個特定的整數(shù)。程序 test.c如下:sQsAEJkW5T#include <std

15、io.h>#include <linux/unistd.h>_syscall1(char*,foo,int,ret> main(>int I,J 。I=100。J=0。J=foo(I> 。printf("This is the result of new kerneln">。printf("%d",j> 。程序編譯:gcc p -I /usr/src/linux-2.4.2/include test.c注意:由于需要引入內(nèi)核頭文件unistd.h,不能簡單的用普通的編譯命令,而應(yīng)該這樣設(shè)置參數(shù)。運行測試程序

16、./test解釋:當函數(shù)還沒有定義在內(nèi)核中時,如果運行以上程序,系統(tǒng)將顯示一個未定義的值-1 ,而在內(nèi)核中定義了以后,系統(tǒng)將顯示100.說明我們內(nèi)核添加系統(tǒng)調(diào)用已經(jīng)成功。GMsIasNXkA3)創(chuàng)建系統(tǒng)調(diào)用 mycall<),實現(xiàn)功能:顯示字符串到屏幕上。<1)編寫系統(tǒng)調(diào)用相應(yīng)的函數(shù)在/usr/src/linux/kernel/sys.c文件中添加如下代碼: asmlinkage void mycall(char *str> printk("%sn",str> 。 注意:在上面的例子中,有一個很少見的特殊函數(shù)printk< ),它的功能與pri

17、ntf< )類似。之所以不用printf<)的原因在于,它不是內(nèi)核的函數(shù)。要在內(nèi)核實現(xiàn)在控制臺顯示字符串的功能,就必須以內(nèi)核所提供的printk< )函數(shù)來代替。Printk< )不同于printf< )的地方是:printk<)會把輸出的結(jié)果送到內(nèi)核的緩沖區(qū)里面,最終調(diào)用控制臺的寫函數(shù)將其打印出來。TIrRGchYzg<2)添加系統(tǒng)調(diào)用號打開文件 /usr/src/linux/include/asm-i386/unistd.h,添加如下一行:7EqZcWLZNX# include _NR_mycall 223/ 因為 _NR_foo 是 222,所以

18、這個只能用 223 了lzq7IGf02E<3)改動系統(tǒng)調(diào)用表打開文件 /usr/src/linux/arch/i386/kernel/entry.s ,在“.longSYMBOL_NAME(sys_foo>",下面添力口 "彳?。?zvpgeqJ1hk.long SYMBOL_NAME(sys_mycall><4)重新編譯內(nèi)核對重新編譯內(nèi)核和使用新內(nèi)核引導(dǎo)熟悉的讀者,可以不必閱讀身份登錄,進入目錄 /usr/src/linux,重建內(nèi)核:rootlinuxserver root# make menuconfigrootlinuxserver roo

19、t# make deprootlinuxserver root# make modules_installrootlinuxserver root#make clean /rootlinuxserver root# make bzImage /<4)和 <5)步。以 rootNrpoJac3v1/配置新內(nèi)核1nowfTG4KI/創(chuàng)建新內(nèi)核fjnFLDa5Zo/ 加入模塊tfnNhnE6e5清除多余創(chuàng)建的文件 HbmVN777sL生成可執(zhí)行內(nèi)核引導(dǎo)文件V7l4jRB8Hsrootlinuxserver root #cp編譯完畢之后,新的內(nèi)核引導(dǎo)文件在目錄:/usr/src/linux

20、/arch/i386/boot/中,叫 baImage.把它復(fù)制到 /boot/ 下面:83lcPA59W9rootlinuxserver root #cp /usr/src/linux/arch/i386/boot/bzImage/boot/ mZkklkzaaP<5)用新的內(nèi)核引導(dǎo)這需要修改文件/etc/lilo.conf,先打開該文件,然后進行修改。修改完成后,存盤退出,運行命令:rootlinuxserver root# /sbin/lilo<6)重新啟動系統(tǒng)、4)編程調(diào)用自己創(chuàng)建的系統(tǒng)調(diào)用系統(tǒng)調(diào)用 mycall<)是讀者自己創(chuàng)建的,自己應(yīng)該對該系統(tǒng)調(diào)用表非常的熟悉。

21、然而使用這個系統(tǒng)調(diào)用還需要注意:系統(tǒng)調(diào)用需要裝換宏。這個轉(zhuǎn)換宏是將系統(tǒng)調(diào)用命令裝換為對應(yīng)參數(shù)的INT80中斷請求,一般格式是syscallN<),這個N可以是06,對應(yīng)與系統(tǒng)調(diào)用的參數(shù)格式,此處 N=1 ,下面是一個簡單的源代碼test1.CAVktR43bpw#include <linux/unistd.h>syscall1(char*,mycall,int,ret>int main(>char *str 。char string50 。str=string 。str="This string will be displayed."。myca

22、ll(str> 。return 0 。實驗二:進程管理實驗指導(dǎo)準備知識基本概念2) 進程的概念3) 進程與程序的區(qū)別4)并發(fā)執(zhí)行的概念5) 進程互斥的概念6) 進程通信的基本概念系統(tǒng)調(diào)用系統(tǒng)調(diào)用是一種進入系統(tǒng)空間的辦法。通常,在 OS的核心中都設(shè)置了一組用于實現(xiàn)各種系統(tǒng)功能的子程序,并將他們提供Z程序員使用。程序員在需要OS提供某種服務(wù)的時候,便可以調(diào)用一條系統(tǒng)調(diào)用命令,去實現(xiàn)希望的功能,這就是系統(tǒng)調(diào)用。因此,系統(tǒng)調(diào)用就像一個黑箱子一樣,對用戶屏蔽了操作系統(tǒng)的具體動作而只是提供了調(diào)用功能的接。ORjBnOwcEd不同的操作系統(tǒng)有各自的系統(tǒng)調(diào)用方法。如Windows API,便是 Wind

23、ows的系統(tǒng)調(diào)用。Linux的系統(tǒng)調(diào)用與之不同的是源于Linux內(nèi)核代碼完全公開,所以可以細致地分析出其系統(tǒng)調(diào)用的機制。2MiJTy0dTT2.1 系統(tǒng)調(diào)用和普通函數(shù)的區(qū)別1) 運行于不同的狀態(tài)用戶程序可以通過系統(tǒng)調(diào)用進入系統(tǒng)空間,在核心態(tài)執(zhí)行;而普通函數(shù)則只能在 用戶空間當中進行。2) 通過軟中斷切斷由于用戶程序使用系統(tǒng)調(diào)用后要進入系統(tǒng)空間,所以需要調(diào)用一個軟中斷;而普通函數(shù)在被調(diào)用時則沒有這個進程。gIiSpiue7A2.2 系統(tǒng)調(diào)用的類型系統(tǒng)調(diào)用的作用與它的宿主操作系統(tǒng)有密切關(guān)系。根據(jù)操作系統(tǒng)的性質(zhì)不同,它們所提供的系統(tǒng)調(diào)用會有一定的差異,不過對于普通操作系統(tǒng)而言,應(yīng)該具有下面幾類系統(tǒng)調(diào)

24、用:uEh0U1Yfmh進程控制類文件操縱類進程通信類信息維護類2.3 系統(tǒng)調(diào)用的實現(xiàn)機制由于操作系統(tǒng)的不同,其系統(tǒng)調(diào)用的實現(xiàn)方式可能不一樣,然而實現(xiàn)機制應(yīng)該大致相同的,一般包含下面兩個步驟。IAg9qLsgBX1) 設(shè)置系統(tǒng)調(diào)用號在系統(tǒng)當中,往往設(shè)置多條系統(tǒng)調(diào)用命令,并賦予每條系統(tǒng)調(diào)用命令一個惟一的系統(tǒng)調(diào)用號。根據(jù)分配系統(tǒng)調(diào)用號方式的不同分為:直接方式和參數(shù)表方式。系統(tǒng)調(diào)用的參數(shù)表方式分為直接和間接兩種方式,如圖1所示。WwghWvVhPE(b)間接方式圖i系統(tǒng)調(diào)用的參數(shù)表方式2) 處理系統(tǒng)調(diào)用操作系統(tǒng)中有一張系統(tǒng)調(diào)用入口表。表中的每個表目都對應(yīng)一條系統(tǒng)調(diào)用命令,它包 含有該系統(tǒng)調(diào)用自帶參數(shù)

25、的數(shù)目、系統(tǒng)調(diào)用命令處理程序的入口地址等等。操作系統(tǒng)內(nèi)核 便是根據(jù)所輸入的系統(tǒng)調(diào)用號在該表中查找到相應(yīng)的系統(tǒng)調(diào)用,進而轉(zhuǎn)入它的入口地址去 執(zhí)行系統(tǒng)調(diào)用程序。asfpsfpi4kLinux的系統(tǒng)調(diào)用機制Linux的系統(tǒng)調(diào)用是通過中斷機制實現(xiàn)的。中斷這個概念涉及計算機系統(tǒng)結(jié)構(gòu)方面的知識,顯然它與微處理器等硬件有著密不可分的關(guān)系。ooeyYZTjjl中斷Interrupt),是指計算機在執(zhí)行期間,系統(tǒng)內(nèi)發(fā)生任何非尋常的或非預(yù)期的急需處理事件,使得 CPU不得不暫時中斷當前正在執(zhí)行的程序而轉(zhuǎn)去執(zhí)行相應(yīng)的事件處理程序,待處理完畢后再返回原來被中斷處繼續(xù)執(zhí)行的進程。其發(fā)生一般而言是異步”的。換句話說就是在

26、無法預(yù)測的情況下發(fā)生的如系統(tǒng)掉電)。所以計算機的軟硬件對于中斷的相應(yīng)反應(yīng)完全是被動的。BkeGuInkxI軟中斷,是對硬中斷的一種模擬,發(fā)送軟中斷就是向接收進程的proc結(jié)構(gòu)中的相應(yīng)項發(fā)送一個特定意義的信號。軟中斷必須等到接收進程執(zhí)行時才能生效的。PgdOOsRlMo陷阱Trap),即由軟件產(chǎn)生的中斷,指處理機和內(nèi)存內(nèi)部產(chǎn)生的中斷,它包括程序運算引起的各種錯誤,如地址非法、校驗錯誤、頁面失效等。它有專門的指令,如X86中的“INTn”,在程序中是有意產(chǎn)生的。所以說陷阱是主動的、同步”的。3cdXwckm15異常Exception ), 一般也是異步的,大多是由于不小心或無意造成的,比如在進行除

27、法操作時除數(shù)為0,就會產(chǎn)生一次異常。h8c52WOngM相關(guān)函數(shù)fork函數(shù)fork)函數(shù)用于創(chuàng)建一個新進程子進程)。其調(diào)用格式為:int fork(。正確返回:等于0,創(chuàng)建子進程,從子進程返回的ID值。等于1 ,從父進程返回的子進程的進程ID值。錯誤返回:等于-1 ,創(chuàng)建失敗。1)子進程和父進程的調(diào)度執(zhí)行子進程被創(chuàng)建后就進入就緒隊列和父進程分別分別獨立地等待調(diào)度。子進程繼承父進程的程序段代碼,子進程被調(diào)度執(zhí)行時,也會和父進程一樣從fork(返回。從共享程序段代碼的角度來看,父進程和子進程所執(zhí)行的程序代碼是同一個,在內(nèi)存中只有一個程序段副本;但是從編程的角度來看,為了使子進程和父進程做不同的事

28、,要在程序中區(qū)分父 進程和子進程的代碼段,這就需要借助于從fork(帶回的值來標志當前程序身份。從知水(返回后,都會執(zhí)行如下語句:v4bdyGiouspid=fork(。得到返回的值pid,有如下幾種情況:(1)若pid小于0,則表示fork(出錯,相應(yīng)語句為if(pid 0 printf("fork errorn" 。exit(0。(2)若pid等于0,則表示當前進程是子進程,繼續(xù)執(zhí)行的后面的代碼是子進程要做 的事,相應(yīng)的語句可寫成if(pid = 0 printf("The child process is running now!n"。exit(0

29、。(3)若pid大于0,則表示當前進程是父進程,繼續(xù)執(zhí)行的后面的代碼是父進程要做的事,相應(yīng)的語句可寫成if(pid > 0> printf("The parent process is running now!n"> 。exit(0>。由于父進程和子進程分別獨立地進入就緒隊列等待調(diào)度,所以誰會先得到調(diào)度是不確 定的,這與系統(tǒng)的調(diào)度策略和系統(tǒng)當前的資源狀態(tài)有關(guān)。因此誰先從fork(>返回,繼續(xù)執(zhí)行后面的語句也是不確定的。J0bm4qMpJ92)父進程和子進程的存放及資源共享當父進程創(chuàng)建子進程時,首先為子進程分配由task向量數(shù)組指向的task_s

30、truct結(jié)構(gòu)的內(nèi)存、所需的堆棧和頁表等,創(chuàng)建進程標識號在系統(tǒng)的進程標識號組中是惟一的),并且將其父進程的進程標識號填入 task_struct中的家族信息中。然后將父進程的 task_struct 的相關(guān)內(nèi)容復(fù)制到子進程的task_struct,對一些數(shù)據(jù)成員進行初始化,如圖 2所示。XVauA9grYP子進程從父進程處繼承的資源包括:真實用戶標識號和組標識號、有效用戶標識號和 組標識號、進程組標識號、對話標識號、控制終端、根目錄與當前工作目錄、設(shè)置用戶標 識號和設(shè)置組標識號計位、信號標識、文件描述符、文件默認創(chuàng)建權(quán)限掩碼、可訪問的內(nèi) 存區(qū)、線程、環(huán)境變量及其他資源分配。bR9c6TJscw

31、用戶內(nèi)存區(qū)一父進程的vhqIrtu I圖2父進程和子進程的內(nèi)存映像父進程數(shù)據(jù)區(qū)重進程堆極區(qū)提率正文區(qū)子進程堆棧區(qū)wait(函數(shù)wait(函數(shù)常用來控制父進程與子進程的同步。在父進程中調(diào)用wait(函數(shù),則父進程被阻塞,進入等待隊列,等待子進程結(jié)束。當子進程結(jié)束時,產(chǎn)生一個終止狀態(tài)字,系統(tǒng)會向父進程發(fā)出SIGCHLD信號。當接到信號后,父進程提取子進程的終止狀態(tài)字,從 wait(函數(shù)返回繼續(xù)執(zhí)行原來的程序。pN9LBDdtrd其調(diào)用格式為:#include <sys/type.h>#include <sys/wait.h>(pid_t> wait(int*statl

32、oc> 。正確返回:大于 0,子進程的進程ID值。等于0,其他。錯誤返回:等于-1,調(diào)用失敗。exit(函數(shù)exit(函數(shù)是進程結(jié)束時最常調(diào)用的函數(shù),在 main(函數(shù)中調(diào)用return,最終也是調(diào)用 exit(函數(shù)。這些都是進程的正常終止。在正常終止時,exit(函數(shù)返回進程結(jié)束狀態(tài)。DJ8T7nHuGT其調(diào)用格式為:#include stdio.hvoid exit(int status。其中,status為進程結(jié)束狀態(tài)。kill(函數(shù)kill(函數(shù)用于刪除執(zhí)行中的程序或者任務(wù)。其調(diào)用格式為:kill(int PID,int IID 。其中,PID是要被殺死的進程號,IID為向?qū)⒈粴?/p>

33、死的進程發(fā)送中的中斷號。Signal(> 函數(shù)signal(函數(shù)是允許調(diào)用進程控制軟中斷信號的處理。其調(diào)用格式為:#include signal.hint sig。void (*func( 。signal(sig,function>。其中,(1) sig的取值如下:信號功能值SIGHUP掛起1SIGINT鍵盤中斷,鍵盤按 Delete鍵或2Break 鍵SIGQUIT鍵盤按Quit鍵3SIGILL非法指令4SIGTRAP跟蹤中斷5SIGIOTIOT指令6SIGBUS總線錯7SIGFPE浮點運算溢出8SIGKILL要求終止進程9SIGUSR1用戶定義信號#110SIGSEGV段違法1

34、1SIGUSR2用戶定義信號#212SIGPIPE向沒有讀進程的管道上寫13SIGALRM定時器告警,時間到14SIGTERMkill發(fā)出的軟件結(jié)束信號15SIGCHLD子進程死17SIGCONT若已停止則繼續(xù)18SIGPWR電源故障30<2) function的解釋如下:SIG_DFL默認操作。對除 SIGPWR和SIGCHLD外所有信號的默認操作是進程終結(jié)。對信號 SIGQUIT、SIGRAP、SIGLL、SIGFPE、SIGBUS 和 SIGSEGV ,它產(chǎn)生一內(nèi)存映像文件。QF81D7bvUASIG_IGN忽視該信號的出現(xiàn)。Function在該進程中的一個函數(shù)地址,在核心返回用戶

35、態(tài)時,它以軟中斷信號的序號作為參數(shù)調(diào)用該函數(shù),對除了信號 SIGILL、SIGTRAP、SIGPWAP以外的信號,核心 自動地重新設(shè)置軟中斷信號處理程序的值SIG_DFL , 一個進程不能捕獲 SIGKILL信號。4B7a9QFw9hpipe(>函數(shù)pipe(>函數(shù)用于創(chuàng)建一個管道。其調(diào)用格式為:#include <unistd.h>pipe(int fp2。其中,fp2是供進程使用的文件描述符數(shù)組,fp0用于寫,fp1用于讀。正確返回:0,調(diào)用成功錯誤返回:-1,調(diào)用失敗。實驗指導(dǎo)進程的軟中斷通信(1) 算法流程圖圖3為進程軟中斷通信的算法流程圖圖3軟中斷通信程序流程

36、圖(2) 參考程序源代碼#include <stdio.h>#include <signal.h>#include <unistd.h>#include <sys/types.h>int wait_flag。void stop( >。main( > /定義兩個進程號int pidl, pid2。變量signal(3,stop>。或者 signal(14,stop>。ix6iFA8xoXwhile(pid1 = fork( >> = -1> 。/若創(chuàng)建子進程 1不成功,則空循環(huán)if(pid1 > 0&

37、gt; /子進程創(chuàng)建成功,pid1為進程號while(pid2 = fork( >> = -1> 。/ 創(chuàng)建子進程 2if(pid2 > 0> wait_flag = 1。sleep(5>。/父進程等待5秒kill(pid1,16>。/ 殺死進程 1kill(pid2,17>。/ 殺死進程 2wait(0>。/等待第1個子進程1結(jié)束的信號wait(0>。/等待第2個子進程2結(jié)束的信號printf("n Parent process is killed !n”> 。exit(0>。/父進程結(jié)束else wait_f

38、lag = 1。signal(17,stop>。/等待進程2被殺死的中斷號 17printf("n Child process 2 is killed by parent !n"> 。 wt6qbkCyDEexit(0>。else wait_flag = 1。signal(16,stop>。/等待進程1被殺死的中斷號 16printf("n Child process 1 is killed by parent !n">Kp5zH46zRkexit(0>。void stop( > wait_flag = 0。 &

39、lt;3)程序運行結(jié)果Child process 1 is killed by parent !Child process 2 is killed by parent !Parent process is killed !或者多次運行,并且 Delete鍵后,會出現(xiàn)如下結(jié)果:Child process 2 is killed by parent ! Child process 1 is killed by parent ! | Parent process is killed !<4)簡要分析1) signal 函數(shù)上述程序中,調(diào)用函數(shù)signal(>都放在一段程序的前面部位,而不

40、是在其他接收信號處。這是因為signal(>的執(zhí)行起的作用只是為進程指定信號量16和17,以及分配相應(yīng)的與stop(>過程連接的指針。因而signal(>函數(shù)必須在程序前面部分執(zhí)行。Yl4HdOAA612) wait函數(shù)在父進程中調(diào)用第 1個wait(0>后,則父進程被阻塞。進入等待第一個子進程運行結(jié)束的隊列,等待子進程結(jié)束。當子進程結(jié)束后,會產(chǎn)生一個終止狀態(tài)字,系統(tǒng)會向父進程發(fā)出SIGCHLD信號。當接到信號后,父進程提取子進程的終止狀態(tài)字,從 wait(>返回繼續(xù)執(zhí)行 原程序。同樣的方式,父進程繼續(xù)執(zhí)行第二個wait(0> ,并再次阻塞,等待第 2個子進

41、程運行結(jié)束。當?shù)诙€子進程運行結(jié)束后父進程繼續(xù)執(zhí)行剩余的語句。ch4PJx4BlI3)關(guān)于exit函數(shù)該函數(shù)中每個進程退出時都用了語句exit(0> ,這是進程的正常終止。在正常終止時,exit(>函數(shù)返回進程結(jié)束狀態(tài)。進程終止時,則由系統(tǒng)內(nèi)核產(chǎn)生一個代表異常終止原因的終止狀態(tài),該進程的父進程都能用wait(>得到其終止狀態(tài)。在子進程調(diào)用exit。后,子進程的結(jié)束狀態(tài)會返回給系統(tǒng)內(nèi)核,由內(nèi)核根據(jù)狀態(tài)字生成終止狀態(tài),供父進程在wait(>中讀取數(shù)據(jù)。若子進程結(jié)束后,父進程還沒有讀取子進程的終止狀態(tài),則子進程就變成了孤兒進程”,系統(tǒng)進程init會自動 收養(yǎng)”該子進程,成為該

42、子進程的父進程,即父進程標識號變成1,當子進程結(jié)束時,init會自動調(diào)用 wait(讀取子進程的遺留數(shù)據(jù),從而避免在系統(tǒng)中留下大量的垃圾。 qd3YfhxCzo4)結(jié)果顯不'上述結(jié)果中 “Child process 1 is killed by parent !和"Child process 2 is killed by parent !相繼出現(xiàn),當運行幾次后,誰在前誰在后是隨機的。這是因為:從進程調(diào)度的角度看,子進程被創(chuàng)建后處于就緒態(tài)。此時,父進程和子進程作為兩個獨立的進程,共享同一個代碼段,分別參加調(diào)度、執(zhí)行,直至進程結(jié)束。但是誰會先被調(diào)度程序選中執(zhí)行,則與系統(tǒng)的調(diào)度策略

43、和系統(tǒng)當前的資源狀態(tài)有關(guān),是不確定的。因此,誰先從fork(函數(shù)中返回繼續(xù)執(zhí)行后面的語句也是不確定的。E836L11DO5進程的管道通信(1) 算法流程圖圖4為基于進程的管道通信的算法流程圖45 / 39圖4管道通信程序流程圖(2) 參考程序源代碼#include <unistd.h>#include <signal.h>#include <stdio.h>int pid1,pid2。/定義兩個進程變量main( > int fd2。/定義兩個字符數(shù)組char OutPipe100,InPipe100。/創(chuàng)建管道pipe(fd>。while(pi

44、d1 = fork( >> = -1> 。/如果進程1創(chuàng)建不成功,則空循環(huán)S42ehLvE3Mif(pid1 = 0 /如果子進程1創(chuàng)建成功,pidl為進程號501nNvZFislockf(fd1,1,0。/ 鎖定管道sprintf(OutPipe,”n Child process 1 is sending message!n”。/ 給 Outpipe賦值 jW1viftGw9write(fd1,OutPipe,50 。sleep(5。lockf(fd1,0,0。exit(0。else while(pid2 = fork( = -1 。xS0DOYWHLP/向管道寫入數(shù)據(jù)/等

45、待讀進程讀出數(shù)據(jù)/解除管道的鎖定/結(jié)束進程1/若進程2創(chuàng)建不成功,則空循環(huán)if(pid2 = 0 lockf(fd1,1,0。sprintf(OutPipe,”n Child process 2 is sending message!n”。LOZMkIqI0wwrite(fd1,OutPipe,50。sleep(5。lockf(fd1,0,0。exit(0。else wait(0。read(fd0,InPipe,50 。printf("%s'n”,InPipe 。wait(0。read(fd0,InPipe,50 。printf("%s'n”,InPipe

46、。exit(0。/等待子進程1結(jié)束/從管道中讀出數(shù)據(jù)/顯示讀出的數(shù)據(jù)/等待子進程2結(jié)束/父進程結(jié)束(3) 程序運行結(jié)果Child process 1 is sending message !Child process 2 is sending message(4) 簡要分析管道,是指用于連接一個讀進程和一個寫進程,以實現(xiàn)它們之間信息的共享文件又稱pipe文件。向管道共享文件)提供輸入的發(fā)送進程即寫進程),以字符流形式將大量的數(shù)據(jù)送入管道;而接收管道輸送的接收進程讀進程),可以從管道中接收數(shù)據(jù)。ZKZUQsUJed為了協(xié)調(diào)雙方的通信,管道通信機制必須提供以下3方面的協(xié)調(diào)能力:互斥。當一個進程正在

47、對pipe進程讀/寫操作時,另一進程必須等待,程序中使用lock(fd1,1,0函數(shù)實現(xiàn)對管道的加鎖操作,用 lock(fd1,0,0解除管道的鎖定。dGY2mcoKtT同步。當寫進程把一定數(shù)量的數(shù)據(jù)寫入pipe后,便去睡眠等待,直到讀進程取走數(shù)據(jù)后,再把它喚醒。當讀進程試圖從一空管道中讀取數(shù)據(jù)時,也應(yīng)睡眠等待,直至寫進程將數(shù)據(jù)寫入管道后,才將其喚醒。rCYbSWRLIA判斷對方是否存在。只有確定寫進程和讀進程都存在的情況下,才能通過管道進行通信。實驗三:存儲器管理實驗準備知識(1) C+、指針、結(jié)構(gòu)體類)(2) HASH表查找方式(3) 操作系統(tǒng)相關(guān)內(nèi)存交換知識(4) 用到的LINUX函數(shù)i

48、nt getpid(獲得當前進程的idvoid srand (int a 以a為種子產(chǎn)生隨機數(shù)int rand(根據(jù)前面的種子,返回一個隨機數(shù)實驗指導(dǎo)本實驗并沒有進入系統(tǒng)空間對實際進程頁面進行控制,而是在用戶空間用線性表的連續(xù)存儲方式對進程頁面交換進行模擬。FyXjoFlMWh3) FIFO算法原理簡述在分配內(nèi)存頁面數(shù)AP)小天進程頁面數(shù)PP)時,當然是最先運行的AP個頁面放入內(nèi)存;這時又需要處理新的頁面,則將原來放的內(nèi)存中的AP個頁中最先進入的調(diào)出FIFO),再將新頁面放入;以后如果再有新頁面需要調(diào)入,則都按上述規(guī)則進行。算法特點:所使用的內(nèi)存頁面構(gòu)成一個隊列。圖表描述假設(shè)某個進程在硬盤上被

49、劃分成5個頁面PP=5),以1、2、3、4、5分別表示,CPU調(diào)用它們的順序這應(yīng)該取決于進程本身)為: 1、4、2、5、3、3、2、4、2、5,如果內(nèi)存可以控制的頁面數(shù)為3AP=3),那么在使用 FIFO算法時,這3個頁面的內(nèi)存使用情況應(yīng)該如圖5所示。TuWrUpPObX圖5不難看出,本例共換入頁面8次,若用變量diseffect表示頁面換入次數(shù),則diseffect=8。算法實現(xiàn)提示要得到命中率,必然應(yīng)該有一個常量total_instruction來記錄頁面總共使用的次數(shù),此外還需要一個變量記錄總共換入頁面的次數(shù)diseffect需要換出頁面總是因為缺頁中斷而產(chǎn)生)。利用公式 1-disef

50、fect / total_instruction*100% 可以得到命中率。 7qWAq9jPqE初始化。設(shè)置兩個數(shù)組 pageap和pagecontrolpp分別表示進程頁面數(shù)和內(nèi)存分配 的頁面數(shù),并產(chǎn)生一個隨機數(shù)序列maintotal_instruction這個序列由pageap的下標隨機構(gòu)成)表示待處理的進程頁面順序,diseffect置0。iiviWTNQFk看main口中是否有下一個元素,若有,就由 main口中獲取該頁面下標,并轉(zhuǎn)3),如果沒有則轉(zhuǎn) 7) 。 yhUQsDgRT1如果該頁已在內(nèi)存中,就轉(zhuǎn) 2),否則轉(zhuǎn)4),同時未命中的diseffect力口 1。觀察pagecont

51、rol是否占滿,如果占滿則須將使用隊列在第6)步中建立的)中最先進入的 就是隊列的第一個單元)pagecontrol單元清干凈”,同時將page口單元 置為不在內(nèi)存中"。MdUZYnKS8I將該page口與pagecontrol口建立對應(yīng)關(guān)系可以改變pagecontrol口的標志位,也可以采用指針鏈接,總之至少要使對應(yīng)的pagecontrol單元包含兩個信息:一是它被使用了,二是哪個page口單元使用的。page口單元也包含兩個信息:對應(yīng)的 pagecontrol單元號和本 page口單元已在內(nèi)存中)。09T7t6eTno將用到的pagecontrol置入使用隊列 這里的隊列是一種F

52、IFO的數(shù)據(jù)結(jié)構(gòu)),返回2)。顯示計算 1-diseffect / total_instruction*100% ,完成。4) LRU算法原理簡述當內(nèi)存分配頁面數(shù)AP)小于進程頁面數(shù)PP)時,把最先執(zhí)行的AP個頁面放入內(nèi)存。當需調(diào)頁面進入內(nèi)存,而當前分配的內(nèi)存頁面全部不空閑時,選擇將其中最長時間沒有用到的那一頁調(diào)出,以空出內(nèi)存來放置新調(diào)入的頁面LRU ) 。 e5TZQIUB5算法特點:每個頁面都有屬性來表示有多長時間未被CPU使用的信息。圖表描述這里采用的例子和前面的一樣。假設(shè)某個進程在硬盤上被劃分成5個頁面PP=5),以1、2、3、4、5分別表示,CPU調(diào)用它們的順序這應(yīng)該取決于進程本身)

53、為: 1、4、2、5、3、3、2、4、2、5,而內(nèi)存可以控制的頁面數(shù)為3AP=3 ),那么在使用LRU算法時,這三個頁面的內(nèi)存使用情況應(yīng)該如圖6所示。sISovAcVQM不難看出,本例共換入頁面7次,若用變量diseffect表示頁面換入次數(shù),則 diseffect=7??诔怯匾步卸鷶?shù)組二,diseffect 能獲彳.向命中pageap卡口pagecontrol的頁面數(shù),并產(chǎn)生一個隨機數(shù)序列maintotal_instruction這個序列由pageap的下標隨機構(gòu)成)表示待處理的進程頁面順序,d seffect置0。GXRw1kFW5s看序歹U main口中是3),如果沒有則卜專作我(UT

54、REMPj累換main口中獲取該頁面下標,并轉(zhuǎn)如果該page口單元在內(nèi)存中便改變頁面屬性,使它保留最近使用”的信息,轉(zhuǎn)<2),否則轉(zhuǎn) <4),同時 diseffect 力口 1。8PQN3NDYyP看是否有空閑頁面,如果有,就返回頁面指針,并轉(zhuǎn)到 5),否則,在內(nèi)存頁面中找出最 長時間沒 有使用 到的頁 面,將其 精干凈”,并返回 該頁面指 針。mLPVzx7ZNw在需處理的page口與4)中得到的pagecontrol口之間建立聯(lián)系,同時讓對應(yīng)的page口單元保存 最新使用”的信息,轉(zhuǎn)2)。AHP35hB02d如果序列處理完成,就輸出計算 1-diseffect / total_

55、instruction*100% 的結(jié)果,完成。NDOcB141gT5) NUR算法原理簡述所謂最近未使用”,首先是要對 近”做一個界定,比如 CLEAR_PERIOD=50 ,便是指 在CPU最近的50次進程頁面處理工作中,都沒有處理到的頁面。那么可能會有以下幾種 情況:1zOk7Ly2VA如果這樣的頁面只有一個,就將其換出,放入需要處理的新頁面。如果有這樣的頁面不止一個,就在這些頁面中任取一個換出可以是下標最小的或者最小的),放入需要處理的頁面。fuNsDv23Kh如果沒有一個這樣的頁面,就隨意換出一個頁面可以是下標最小的或者最大的)。算法特點:有一個循環(huán)周期,每到達這個周期,所有頁面存放是否被CPU處理的信息的屬性均被置于初始態(tài) 沒有被訪問)。tqMB9ew4YX圖表描述還是用前面的例子,某進程在硬盤上被劃分為5個頁面,用1、2、3、4、5表示,而處理及處理它們的順序為:1、4、2、5、3、3

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論