




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、實(shí)驗(yàn)一UNIX/LINUX及其使用環(huán)境(二)LINUX下C語言使用、編譯與調(diào)試實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、復(fù)習(xí)C語言程序基本知識(shí)2、練習(xí)并掌握UNIX提供的vi編輯器來編譯C程序3、學(xué)會(huì)利用gcc、gdb編譯、調(diào)試C程序?qū)嶒?yàn)內(nèi)容1、用vi編寫一個(gè)簡(jiǎn)單的、顯示Hello,World!的C程序,用gcc編譯并觀察編譯后的結(jié)果2、利用gdb調(diào)試該程序3、運(yùn)行生成的可執(zhí)行文件。實(shí)驗(yàn)指導(dǎo)一、C語言使用簡(jiǎn)介L(zhǎng)INUX中包含了很多軟件開發(fā)工具。它們中的很多是用于C和C+應(yīng)用程序開發(fā)的。C是一種能在UNIX的早期就被廣泛使用的通用編程語言。它最早是由Bell實(shí)驗(yàn)室的DennisRitchie為了UNIX的輔助開發(fā)而寫的,
2、從此C就成為世界上使用最廣泛的計(jì)算機(jī)語言。C能在編程領(lǐng)域里得到如此廣泛支持的原因有:(1)它是一種非常通用的語言,并且它的語法和函數(shù)庫在不同的平臺(tái)上都是統(tǒng)一的,對(duì)開發(fā)者非常有吸引力;(2)用C寫的程序執(zhí)行速度很快;(3)C是所有版本UNIX上的系統(tǒng)語言;二、文件編輯器vivi是在UNIX上被廣泛使用的中英文編輯軟件。vi是visualeditor的縮寫,是UNIX提供給用戶的一個(gè)窗口化編輯環(huán)境。進(jìn)入vi,直接執(zhí)行vi編輯程序即可。例:$vitest.c顯示器出現(xiàn)vi的編輯窗口,同時(shí)vi會(huì)將文件復(fù)制一份至緩沖區(qū)(buffer)。vi先對(duì)緩沖區(qū)的文件進(jìn)行編輯,保留在磁盤中的文件則不變。編輯完成后,
3、使用者可決定是否要取代原來舊有的文件。1、vi的工作模式vi提供二種工作模式:輸入模式(insertmode)和命令模式(commandmode)。使用者進(jìn)入vi后,即處在命令模式下,此刻鍵入的任何字符皆被視為命令,可進(jìn)行刪除、修改、存盤等操作。要輸入信息,應(yīng)轉(zhuǎn)換到輸入模式。(1)命令模式在輸入模式下,按ESC可切換到命令模式。命令模式下,可選用下列指令離開vi:q!離開vi,并放棄剛在緩沖區(qū)內(nèi)編輯的內(nèi)容:wq將緩沖區(qū)內(nèi)的資料寫入磁盤中,并離開vi:ZZ同wq:x同wq:w將緩沖區(qū)內(nèi)的資料寫入磁盤中,但并不離開vi:q離開vi,若文件被修改過,則要被要求確認(rèn)是否放棄修改的內(nèi)容,此指令可與:w配
4、合使用(2)命令模式下光標(biāo)的移動(dòng)H左移一個(gè)字符J下移一個(gè)字符K上移一個(gè)字符L右移一個(gè)字符0移至該行的首$移至該行的末移至該行的第一個(gè)字符處H移至窗口的第一列M移至窗口中間那一列L移至窗口的最后一列G移至該文件的最后一列W,W下一個(gè)單詞(W忽略標(biāo)點(diǎn))B,B上一個(gè)單詞(B忽略標(biāo)點(diǎn))+移至下一列的第一個(gè)字符處-移至上一列的第一個(gè)字符處(移至該句首)移至該句末移至該段首移至該段末NG移至該文件的第n列N+移至光標(biāo)所在位置之后第n列n-移至光標(biāo)所在位置之前第n列(3)輸入模式輸入以下命令即可進(jìn)入vi輸入模式:a(append)在光標(biāo)之后加入資料A在該行之末加入資料i(insert)在光標(biāo)之前加入資料I在
5、該行之首加入資料o(open)新增一行于該行之下,供輸入資料用O新增一行于該行之上,供輸入資料用Dd刪除當(dāng)前光標(biāo)所在行X刪除當(dāng)前光標(biāo)字符X刪除當(dāng)前光標(biāo)之前字符U撤消重做F查找s替換,例如:將文件中的所有FOX換成duck,用:%s/FOX/duck/gESC離開輸入模式更多用法見infovi三、GNUC編譯器LINUX上可用的C編譯器是GNUC編譯器,它建立在自由軟件基金會(huì)編程許可證的基礎(chǔ)上,因此可以自由發(fā)布。LINUX上的GNUC編譯器(GCC)是一個(gè)全功能的ANCIC兼容編譯器,而一般UNIX(如SCOUNIX)用的編譯器是CC。下面介紹GCC和一些GCC編譯器最常用的選項(xiàng)。1、使用GCC
6、通常后跟一些選項(xiàng)和文件名來使用GCC編譯器。GCC命令的基本用法如下:gccoptionsfilenames命令行選項(xiàng)指定的編譯過程中的具體操作2、GCC常用選項(xiàng)GCC有超過100個(gè)的編譯選項(xiàng)可用,這些選項(xiàng)中的許多可能永遠(yuǎn)都不會(huì)用到,但一些主要的選項(xiàng)將會(huì)頻繁使用。很多的GCC選項(xiàng)包括一個(gè)以上的字符,因此必須為每個(gè)選項(xiàng)指定各自的連字符,并且就像大多數(shù)LINUX命令一樣不能在一個(gè)單獨(dú)的連字符后跟一組選項(xiàng)。例如,下面的命令是不同的:gcc-p-gtest.cgcc-pgtest.c第一條命令告訴GCC編譯test.c時(shí)為prof命令建立剖析(profile)信息并且把調(diào)試信息加入到可執(zhí)行文件里。第二
7、條命令告訴GCC只為gprof命令建立剖析信息。當(dāng)不用任何選項(xiàng)編譯一個(gè)程序時(shí),GCC將建立(假定編譯成功)一個(gè)名為a.out的可執(zhí)行文件。例如,gcctest.c編譯成功后,當(dāng)前目錄下就產(chǎn)生了一個(gè)a.out文件。也可用-o選項(xiàng)來為即將產(chǎn)生的可執(zhí)行文件指定一個(gè)文件名來代替a.out。例如:gccocountcount.c此時(shí)得到的可執(zhí)行文件就不再是a.out,而是count。GCC也可以指定編譯器處理步驟多少。-c選項(xiàng)告訴GCC僅把源代碼編譯為目標(biāo)代碼而跳過匯編和連接步驟。這個(gè)選項(xiàng)使用得非常頻繁因?yàn)樗幾g多個(gè)C程序時(shí)速度更快且更易于管理。默認(rèn)時(shí)GCC建立的目標(biāo)代碼文件有一個(gè).o的擴(kuò)展名。3、執(zhí)行
8、文件格式:./可執(zhí)行文件名例:./a.out./count三、gdb調(diào)試工具LINUX包含了一個(gè)叫g(shù)db的GNU調(diào)試程序。gdb是一個(gè)用來調(diào)試C和C+程序的強(qiáng)有力調(diào)試器。它使你能在程序運(yùn)行時(shí)觀察程序的內(nèi)部結(jié)構(gòu)和內(nèi)存的使用情況。它具有以下一些功能:監(jiān)視程序中變量的值;設(shè)置斷點(diǎn)以使程序在指定的代碼行上停止執(zhí)行;一行行的執(zhí)行代碼。以下是利用gdb進(jìn)行調(diào)試的步驟:1、調(diào)試編譯代碼為了使gdb正常工作,必須使你的程序在編譯時(shí)包含調(diào)試信息。調(diào)試信息里包含你程序里的每個(gè)變量的類型和在可執(zhí)行文件里的地址映射以及源代碼的行號(hào)。gdb利用這些信息使源代碼和機(jī)器碼相關(guān)聯(lián)。在編譯時(shí)用g選項(xiàng)打開調(diào)試選項(xiàng)。2、gdb基本
9、命令命令描述file裝入欲調(diào)試的可執(zhí)行文件kill終止正在調(diào)試的程序list列出產(chǎn)生執(zhí)行文件的源代碼部分next執(zhí)行一行源代碼但不進(jìn)入函數(shù)內(nèi)部step執(zhí)行一行源代碼并進(jìn)入函數(shù)內(nèi)部run執(zhí)行當(dāng)前被調(diào)試的程序quit終止gdbwatch監(jiān)視一個(gè)變量的值而不管它何時(shí)被改變break在代碼里設(shè)置斷點(diǎn),使程序執(zhí)行到這里時(shí)被掛起make不退出gdb就可以重新產(chǎn)生可執(zhí)行文件shell不離開gdb就執(zhí)行UNIXshell命令3、應(yīng)用舉例(1)設(shè)有一源程序greet.c(2)編譯,gcc-ggdbogreetgreet.c,出錯(cuò)(3)gdbgreet,出現(xiàn)提示符(gdb),此時(shí)可在提示符下輸入gdb的命令了,如
10、:(gdb)run(gdb)list(4)退出調(diào)試狀態(tài),返回系統(tǒng)提示符下,(gdb)quit四、參考程序main()printf(Hello,world!n);實(shí)驗(yàn)二進(jìn)程管理(一)進(jìn)程的創(chuàng)建實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、掌握進(jìn)程的概念,明確進(jìn)程的含義2、認(rèn)識(shí)并了解并發(fā)執(zhí)行的實(shí)質(zhì)實(shí)驗(yàn)內(nèi)容1、編寫一段程序,使用系統(tǒng)調(diào)用fork()創(chuàng)建兩個(gè)子進(jìn)程。當(dāng)此程序運(yùn)行時(shí),在系統(tǒng)中有一個(gè)父進(jìn)程和兩個(gè)子進(jìn)程活動(dòng)。讓每一個(gè)進(jìn)程在屏幕上顯示一個(gè)字符:父進(jìn)程顯示a,子進(jìn)程分別顯示字符b和字符c。試觀察記錄屏幕上的顯示結(jié)果,并分析原因。2、修改上述程序,每一個(gè)進(jìn)程循環(huán)顯示一句話。子進(jìn)程顯示daughter及son,父進(jìn)程顯示pare
11、nt,觀察結(jié)果,分析原因。實(shí)驗(yàn)準(zhǔn)備(1)閱讀LINUX的fork.c源碼文件(見附錄二),分析進(jìn)程的創(chuàng)建過程。(2)閱讀LINUX的sched.c源碼文件(見附錄三),加深對(duì)進(jìn)程管理概念的認(rèn)識(shí)。實(shí)驗(yàn)指導(dǎo)一、進(jìn)程UNIX中,進(jìn)程既是一個(gè)獨(dú)立擁有資源的基本單位,又是一個(gè)獨(dú)立調(diào)度的基本單位。一個(gè)進(jìn)程實(shí)體由若干個(gè)區(qū)(段)組成,包括程序區(qū)、數(shù)據(jù)區(qū)、棧區(qū)、共享存儲(chǔ)區(qū)等。每個(gè)區(qū)又分為若干頁,每個(gè)進(jìn)程配置有唯一的進(jìn)程控制塊PCB,用于控制和管理進(jìn)程。PCB的數(shù)據(jù)結(jié)構(gòu)如下:1、進(jìn)程表項(xiàng)(ProcessTableEntry)。包括一些最常用的核心數(shù)據(jù):進(jìn)程標(biāo)識(shí)符PID、用戶標(biāo)識(shí)符UID、進(jìn)程狀態(tài)、事件描述符、進(jìn)程
12、和U區(qū)在內(nèi)存或外存的地址、軟中斷信號(hào)、計(jì)時(shí)域、進(jìn)程的大小、偏置值nice、指向就緒隊(duì)列中下一個(gè)PCB的指針P_Link、指向U區(qū)進(jìn)程正文、數(shù)據(jù)及棧在內(nèi)存區(qū)域的指針。2、U區(qū)(UArea)。用于存放進(jìn)程表項(xiàng)的一些擴(kuò)充信息。每一個(gè)進(jìn)程都有一個(gè)私用的U區(qū),其中含有:進(jìn)程表項(xiàng)指針、真正用戶標(biāo)識(shí)符u-ruid(readuserID)、有效用戶標(biāo)識(shí)符u-euid(effectiveuserID)、用戶文件描述符表、計(jì)時(shí)器、內(nèi)部I/O參數(shù)、限制字段、差錯(cuò)字段、返回值、信號(hào)處理數(shù)組。由于UNIX系統(tǒng)采用段頁式存儲(chǔ)管理,為了把段的起始虛地址變換為段在系統(tǒng)中的物理地址,便于實(shí)現(xiàn)區(qū)的共享,所以還有:3、系統(tǒng)區(qū)表項(xiàng)。
13、以存放各個(gè)段在物理存儲(chǔ)器中的位置等信息。系統(tǒng)把一個(gè)進(jìn)程的虛地址空間劃分為若干個(gè)連續(xù)的邏輯區(qū),有正文區(qū)、數(shù)據(jù)區(qū)、棧區(qū)等。這些區(qū)是可被共享和保護(hù)的獨(dú)立實(shí)體,多個(gè)進(jìn)程可共享一個(gè)區(qū)。為了對(duì)區(qū)進(jìn)行管理,核心中設(shè)置一個(gè)系統(tǒng)區(qū)表,各表項(xiàng)中記錄了以下有關(guān)描述活動(dòng)區(qū)的信息:區(qū)的類型和大小、區(qū)的狀態(tài)、區(qū)在物理存儲(chǔ)器中的位置、引用計(jì)數(shù)、指向文件索引結(jié)點(diǎn)的指針。4、進(jìn)程區(qū)表系統(tǒng)為每個(gè)進(jìn)程配置了一張進(jìn)程區(qū)表。表中,每一項(xiàng)記錄一個(gè)區(qū)的起始虛地址及指向系統(tǒng)區(qū)表中對(duì)應(yīng)的區(qū)表項(xiàng)。核心通過查找進(jìn)程區(qū)表和系統(tǒng)區(qū)表,便可將區(qū)的邏輯地址變換為物理地址。二、進(jìn)程映像UNIX系統(tǒng)中,進(jìn)程是進(jìn)程映像的執(zhí)行過程,也就是正在執(zhí)行的進(jìn)程實(shí)體。它由
14、三部分組成:1、用戶級(jí)上、下文。主要成分是用戶程序;2、寄存器上、下文。由CPU中的一些寄存器的內(nèi)容組成,如PC,PSW,SP及通用寄存器等;3、系統(tǒng)級(jí)上、下文。包括OS為管理進(jìn)程所用的信息,有靜態(tài)和動(dòng)態(tài)之分。三、所涉及的系統(tǒng)調(diào)用1、fork()創(chuàng)建一個(gè)新進(jìn)程。系統(tǒng)調(diào)用格式:pid=fork()參數(shù)定義:intfork()fork()返回值意義如下:0:在子進(jìn)程中,pid變量保存的fork()返回值為0,表示當(dāng)前進(jìn)程是子進(jìn)程。0:在父進(jìn)程中,pid變量保存的fork()返回值為子進(jìn)程的id值(進(jìn)程唯一標(biāo)識(shí)符)。-1:創(chuàng)建失敗。如果fork()調(diào)用成功,它向父進(jìn)程返回子進(jìn)程的PID,并向子進(jìn)程返
15、回0,即fork()被調(diào)用了一次,但返回了兩次。此時(shí)OS在內(nèi)存中建立一個(gè)新進(jìn)程,所建的新進(jìn)程是調(diào)用fork()父進(jìn)程(parentprocess)的副本,稱為子進(jìn)程(childprocess)。子進(jìn)程繼承了父進(jìn)程的許多特性,并具有與父進(jìn)程完全相同的用戶級(jí)上下文。父進(jìn)程與子進(jìn)程并發(fā)執(zhí)行。核心為fork()完成以下操作:(1)為新進(jìn)程分配一進(jìn)程表項(xiàng)和進(jìn)程標(biāo)識(shí)符進(jìn)入fork()后,核心檢查系統(tǒng)是否有足夠的資源來建立一個(gè)新進(jìn)程。若資源不足,則fork()系統(tǒng)調(diào)用失??;否則,核心為新進(jìn)程分配一進(jìn)程表項(xiàng)和唯一的進(jìn)程標(biāo)識(shí)符。(2)檢查同時(shí)運(yùn)行的進(jìn)程數(shù)目超過預(yù)先規(guī)定的最大數(shù)目時(shí),fork()系統(tǒng)調(diào)用失敗。(3
16、)拷貝進(jìn)程表項(xiàng)中的數(shù)據(jù)將父進(jìn)程的當(dāng)前目錄和所有已打開的數(shù)據(jù)拷貝到子進(jìn)程表項(xiàng)中,并置進(jìn)程的狀態(tài)為“創(chuàng)建”狀態(tài)。(4)子進(jìn)程繼承父進(jìn)程的所有文件對(duì)父進(jìn)程當(dāng)前目錄和所有已打開的文件表項(xiàng)中的引用計(jì)數(shù)加1。(5)為子進(jìn)程創(chuàng)建進(jìn)程上、下文進(jìn)程創(chuàng)建結(jié)束,設(shè)子進(jìn)程狀態(tài)為“內(nèi)存中就緒”并返回子進(jìn)程的標(biāo)識(shí)符。(6)子進(jìn)程執(zhí)行雖然父進(jìn)程與子進(jìn)程程序完全相同,但每個(gè)進(jìn)程都有自己的程序計(jì)數(shù)器PC(注意子進(jìn)程的PC開始位置),然后根據(jù)pid變量保存的fork()返回值的不同,執(zhí)行了不同的分支語句。例:.pid=fork();if(!pid)printf(Imthechildprocess!n);elseif(pid0)p
17、rintf(Imtheparentprocess!n);elseprintf(Forkfail!n);fork()調(diào)用前fork()調(diào)用后.pid=fork();if(!pid)printf(Imthechildprocess!n);elseif(pid0)printf(Imtheparentprocess!n);elseprintf(Forkfail!n);.pid=fork();if(!pid)printf(Imthechildprocess!n);elseif(pid0)printf(Imtheparentprocess!n);elseprintf(Forkfail!n);四、參考程序1
18、、#includemain()intp1,p2;while(p1=fork()=-1);/*創(chuàng)建子進(jìn)程p1*/if(p1=0)putchar(b);elsewhile(p2=fork()=-1);/*創(chuàng)建子進(jìn)程p2*/if(p2=0)putchar(c);elseputchar(a);2、#includemain()intp1,p2,i;while(p1=fork()=-1);/*創(chuàng)建子進(jìn)程p1*/if(p1=0)for(i=0;i10;i+)printf(daughter%dn,i);elsewhile(p2=fork()=-1);/*創(chuàng)建子進(jìn)程p2*/if(p2=0)for(i=0;i10
19、;i+)printf(son%dn,i);elsefor(i=0;i10;i+)printf(parent%dn,i);五、運(yùn)行結(jié)果1、bca,bac,abc,都有可能。2、parentsondaughter.daughter.或parentsonparentdaughter等六、分析原因除strace外,也可用ltrace-f-i-S./executable-file-name查看以上程序執(zhí)行過程。1、從進(jìn)程并發(fā)執(zhí)行來看,各種情況都有可能。上面的三個(gè)進(jìn)程沒有同步措施,所以父進(jìn)程與子進(jìn)程的輸出內(nèi)容會(huì)疊加在一起。輸出次序帶有隨機(jī)性。2、由于函數(shù)printf()在輸出字符串時(shí)不會(huì)被中斷,因此,字符
20、串內(nèi)部字符順序輸出不變。但由于進(jìn)程并發(fā)執(zhí)行的調(diào)度順序和父子進(jìn)程搶占處理機(jī)問題,輸出字符串的順序和先后隨著執(zhí)行的不同而發(fā)生變化。這與打印單字符的結(jié)果相同。補(bǔ)充:進(jìn)程樹在UNIX系統(tǒng)中,只有0進(jìn)程是在系統(tǒng)引導(dǎo)時(shí)被創(chuàng)建的,在系統(tǒng)初啟時(shí)由0進(jìn)程創(chuàng)建1進(jìn)程,以后0進(jìn)程變成對(duì)換進(jìn)程,1進(jìn)程成為系統(tǒng)中的始祖進(jìn)程。UNIX利用fork()為每個(gè)終端創(chuàng)建一個(gè)子進(jìn)程為用戶服務(wù),如等待用戶登錄、執(zhí)行SHELL命令解釋程序等,每個(gè)終端進(jìn)程又可利用fork()來創(chuàng)建其子進(jìn)程,從而形成一棵進(jìn)程樹??梢哉f,系統(tǒng)中除0進(jìn)程外的所有進(jìn)程都是用fork()創(chuàng)建的。七、思考題(1)系統(tǒng)是怎樣創(chuàng)建進(jìn)程的?(2)當(dāng)首次調(diào)用新創(chuàng)建進(jìn)程時(shí)
21、,其入口在哪里?實(shí)驗(yàn)二進(jìn)程管理(二)進(jìn)程的控制實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、掌握進(jìn)程另外的創(chuàng)建方法2、熟悉進(jìn)程的睡眠、同步、撤消等進(jìn)程控制方法實(shí)驗(yàn)內(nèi)容1、用fork()創(chuàng)建一個(gè)進(jìn)程,再調(diào)用exec()用新的程序替換該子進(jìn)程的內(nèi)容2、利用wait()來控制進(jìn)程執(zhí)行順序?qū)嶒?yàn)指導(dǎo)一、所涉及的系統(tǒng)調(diào)用在UNIX/LINUX中fork()是一個(gè)非常有用的系統(tǒng)調(diào)用,但在UNIX/LINUX中建立進(jìn)程除了fork()之外,也可用與fork()配合使用的exec()。1、exec()系列系統(tǒng)調(diào)用exec()系列,也可用于新程序的運(yùn)行。fork()只是將父進(jìn)程的用戶級(jí)上下文拷貝到新進(jìn)程中,而exec()系列可以將一個(gè)可執(zhí)行的
22、二進(jìn)制文件覆蓋在新進(jìn)程的用戶級(jí)上下文的存儲(chǔ)空間上,以更改新進(jìn)程的用戶級(jí)上下文。exec()系列中的系統(tǒng)調(diào)用都完成相同的功能,它們把一個(gè)新程序裝入內(nèi)存,來改變調(diào)用進(jìn)程的執(zhí)行代碼,從而形成新進(jìn)程。如果exec()調(diào)用成功,調(diào)用進(jìn)程將被覆蓋,然后從新程序的入口開始執(zhí)行,這樣就產(chǎn)生了一個(gè)新進(jìn)程,新進(jìn)程的進(jìn)程標(biāo)識(shí)符id與調(diào)用進(jìn)程相同。exec()沒有建立一個(gè)與調(diào)用進(jìn)程并發(fā)的子進(jìn)程,而是用新進(jìn)程取代了原來進(jìn)程。所以exec()調(diào)用成功后,沒有任何數(shù)據(jù)返回,這與fork()不同。exec()系列系統(tǒng)調(diào)用在UNIX系統(tǒng)庫unistd.h中,共有execl、execlp、execle、execv、execvp五
23、個(gè),其基本功能相同,只是以不同的方式來給出參數(shù)。一種是直接給出參數(shù)的指針,如:intexecl(path,arg0,arg1,.argn,0);char*path,*arg0,*arg1,.,*argn;另一種是給出指向參數(shù)表的指針,如:intexecv(path,argv);char*path,*argv;具體使用可參考有關(guān)書。2、exec()和fork()聯(lián)合使用系統(tǒng)調(diào)用exec和fork()聯(lián)合使用能為程序開發(fā)提供有力支持。用fork()建立子進(jìn)程,然后在子進(jìn)程中使用exec(),這樣就實(shí)現(xiàn)了父進(jìn)程與一個(gè)與它完全不同子進(jìn)程的并發(fā)執(zhí)行。一般,wait、exec聯(lián)合使用的模型為:intsta
24、tus;.if(fork()=0).;execl(.);.;wait(&status);3、wait()等待子進(jìn)程運(yùn)行結(jié)束。如果子進(jìn)程沒有完成,父進(jìn)程一直等待。wait()將調(diào)用進(jìn)程掛起,直至其子進(jìn)程因暫?;蚪K止而發(fā)來軟中斷信號(hào)為止。如果在wait()前已有子進(jìn)程暫?;蚪K止,則調(diào)用進(jìn)程做適當(dāng)處理后便返回。系統(tǒng)調(diào)用格式:intwait(status)int*status;其中,status是用戶空間的地址。它的低8位反應(yīng)子進(jìn)程狀態(tài),為0表示子進(jìn)程正常結(jié)束,非0則表示出現(xiàn)了各種各樣的問題;高8位則帶回了exit()的返回值。exit()返回值由系統(tǒng)給出。核心對(duì)wait()作以下處理:(1)首先查找
25、調(diào)用進(jìn)程是否有子進(jìn)程,若無,則返回出錯(cuò)碼;(2)若找到一處于“僵死狀態(tài)”的子進(jìn)程,則將子進(jìn)程的執(zhí)行時(shí)間加到父進(jìn)程的執(zhí)行時(shí)間上,并釋放子進(jìn)程的進(jìn)程表項(xiàng);(3)若未找到處于“僵死狀態(tài)”的子進(jìn)程,則調(diào)用進(jìn)程便在可被中斷的優(yōu)先級(jí)上睡眠,等待其子進(jìn)程發(fā)來軟中斷信號(hào)時(shí)被喚醒。4、exit()終止進(jìn)程的執(zhí)行。系統(tǒng)調(diào)用格式:voidexit(status)intstatus;其中,status是返回給父進(jìn)程的一個(gè)整數(shù),以備查考。為了及時(shí)回收進(jìn)程所占用的資源并減少父進(jìn)程的干預(yù),UNIX/LINUX利用exit()來實(shí)現(xiàn)進(jìn)程的自我終止,通常父進(jìn)程在創(chuàng)建子進(jìn)程時(shí),應(yīng)在進(jìn)程的末尾安排一條exit(),使子進(jìn)程自我終止
26、。exit(0)表示進(jìn)程正常終止,exit(1)表示進(jìn)程運(yùn)行有錯(cuò),異常終止。如果調(diào)用進(jìn)程在執(zhí)行exit()時(shí),其父進(jìn)程正在等待它的終止,則父進(jìn)程可立即得到其返回的整數(shù)。核心須為exit()完成以下操作:(1)關(guān)閉軟中斷(2)回收資源(3)寫記帳信息(4)置進(jìn)程為“僵死狀態(tài)”二、參考程序#include#includemain()intpid;pid=fork();/*創(chuàng)建子進(jìn)程*/switch(pid)case-1:/*創(chuàng)建失敗*/printf(forkfail!n);exit(1);case0:/*子進(jìn)程*/execl(/bin/ls,ls,-1,-color,NULL);printf(ex
27、ecfail!n);exit(1);default:/*父進(jìn)程*/wait(NULL);/*同步*/printf(lscompleted!n);exit(0);三、運(yùn)行結(jié)果執(zhí)行命令ls-l-color,(按倒序)列出當(dāng)前目錄下所有文件和子目錄;lscompleted!四、分析原因程序在調(diào)用fork()建立一個(gè)子進(jìn)程后,馬上調(diào)用wait(),使父進(jìn)程在子進(jìn)程結(jié)束之前,一直處于睡眠狀態(tài)。子進(jìn)程用exec()裝入命令ls,exec()后,子進(jìn)程的代碼被ls的代碼取代,這時(shí)子進(jìn)程的PC指向ls的第1條語句,開始執(zhí)行l(wèi)s的命令代碼。注意在這里wait()給我們提供了一種實(shí)現(xiàn)進(jìn)程同步的簡(jiǎn)單方法。五、思考(
28、1)可執(zhí)行文件加載時(shí)進(jìn)行了哪些處理?(2)什么是進(jìn)程同步?wait()是如何實(shí)現(xiàn)進(jìn)程同步的?實(shí)驗(yàn)二進(jìn)程管理(三)進(jìn)程互斥實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、進(jìn)一步認(rèn)識(shí)并發(fā)執(zhí)行的實(shí)質(zhì)2、分析進(jìn)程競(jìng)爭(zhēng)資源的現(xiàn)象,學(xué)習(xí)解決進(jìn)程互斥的方法實(shí)驗(yàn)內(nèi)容1、修改實(shí)驗(yàn)(一)中的程序2,用lockf()來給每一個(gè)進(jìn)程加鎖,以實(shí)現(xiàn)進(jìn)程之間的互斥2、觀察并分析出現(xiàn)的現(xiàn)象實(shí)驗(yàn)指導(dǎo)一、所涉及的系統(tǒng)調(diào)用lockf(files,function,size)用作鎖定文件的某些段或者整個(gè)文件。本函數(shù)的頭文件為#includeunistd.h參數(shù)定義:intlockf(files,function,size)intfiles,function;lon
29、gsize;其中:files是文件描述符;function是鎖定和解鎖:1表示鎖定,0表示解鎖。size是鎖定或解鎖的字節(jié)數(shù),為0,表示從文件的當(dāng)前位置到文件尾。二、參考程序#include#includemain()intp1,p2,i;while(p1=fork()=-1);/*創(chuàng)建子進(jìn)程p1*/if(p1=0)lockf(1,1,0);/*加鎖,這里第一個(gè)參數(shù)為stdout(標(biāo)準(zhǔn)輸出設(shè)備的描述符)*/for(i=0;i10;i+)printf(daughter%dn,i);lockf(1,0,0);/*解鎖*/elsewhile(p2=fork()=-1);/*創(chuàng)建子進(jìn)程p2*/if(p
30、2=0)lockf(1,1,0);/*加鎖*/for(i=0;i10;i+)printf(son%dn,i);lockf(1,0,0);/*解鎖*/elselockf(1,1,0);/*加鎖*/for(i=0;i10;i+)printf(parent%dn,i);lockf(1,0,0);/*解鎖*/三、運(yùn)行結(jié)果parentsondaughter.daughter.或parentsonparentdaughter大致與未上鎖的輸出結(jié)果相同,也是隨著執(zhí)行時(shí)間不同,輸出結(jié)果的順序有所不同。四、分析原因上述程序執(zhí)行時(shí),不同進(jìn)程之間不存在共享臨界資源(其中打印機(jī)的互斥性已由操作系統(tǒng)保證)問題,所以加鎖
31、與不加鎖效果相同。五、分析以下程序的輸出結(jié)果:#include#includemain()intp1,p2,i;int*fp;fp=fopen(to_be_locked.txt,w+);if(fp=NULL)printf(Failtocreatefile);exit(-1);while(p1=fork()=-1);/*創(chuàng)建子進(jìn)程p1*/if(p1=0)lockf(*fp,1,0);/*加鎖*/for(i=0;i10;i+)fprintf(fp,daughter%dn,i);lockf(*fp,0,0);/*解鎖*/elsewhile(p2=fork()=-1);/*創(chuàng)建子進(jìn)程p2*/if(p2
32、=0)lockf(*fp,1,0);/*加鎖*/for(i=0;i10;i+)fprintf(fp,son%dn,i);lockf(*fp,0,0);/*解鎖*/elsewait(NULL);lockf(*fp,1,0);/*加鎖*/for(i=0;i10;i+)fprintf(fp,parent%dn,i);lockf(*fp,0,0);/*解鎖*/fclose(fp);catto_be_locked.txt查看輸出結(jié)果實(shí)驗(yàn)三進(jìn)程間通信UNIX/LINUX系統(tǒng)的進(jìn)程間通信機(jī)構(gòu)(IPC)允許在任意進(jìn)程間大批量地交換數(shù)據(jù)。本實(shí)驗(yàn)的目的是了解和熟悉LINUX支持的信號(hào)量機(jī)制、管道機(jī)制、消息通信機(jī)制
33、及共享存儲(chǔ)區(qū)機(jī)制。(一)信號(hào)機(jī)制實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、了解什么是信號(hào)2、熟悉LINUX系統(tǒng)中進(jìn)程之間軟中斷通信的基本原理實(shí)驗(yàn)內(nèi)容1、編寫程序:用fork()創(chuàng)建兩個(gè)子進(jìn)程,再用系統(tǒng)調(diào)用signal()讓父進(jìn)程捕捉鍵盤上來的中斷信號(hào)(即按c鍵);捕捉到中斷信號(hào)后,父進(jìn)程用系統(tǒng)調(diào)用kill()向兩個(gè)子進(jìn)程發(fā)出信號(hào),子進(jìn)程捕捉到信號(hào)后分別輸出下列信息后終止:Childprocess1iskilledbyparent!Childprocess2iskilledbyparent!父進(jìn)程等待兩個(gè)子進(jìn)程終止后,輸出如下的信息后終止:Parentprocessiskilled!2、分析利用軟中斷通信實(shí)現(xiàn)進(jìn)程同步的機(jī)
34、理實(shí)驗(yàn)指導(dǎo)一、信號(hào)1、信號(hào)的基本概念每個(gè)信號(hào)都對(duì)應(yīng)一個(gè)正整數(shù)常量(稱為signalnumber,即信號(hào)編號(hào)。定義在系統(tǒng)頭文件中),代表同一用戶的諸進(jìn)程之間傳送事先約定的信息的類型,用于通知某進(jìn)程發(fā)生了某異常事件。每個(gè)進(jìn)程在運(yùn)行時(shí),都要通過信號(hào)機(jī)制來檢查是否有信號(hào)到達(dá)。若有,便中斷正在執(zhí)行的程序,轉(zhuǎn)向與該信號(hào)相對(duì)應(yīng)的處理程序,以完成對(duì)該事件的處理;處理結(jié)束后再返回到原來的斷點(diǎn)繼續(xù)執(zhí)行。實(shí)質(zhì)上,信號(hào)機(jī)制是對(duì)中斷機(jī)制的一種模擬,故在早期的UNIX版本中又把它稱為軟中斷。信號(hào)與中斷的相似點(diǎn):(1)采用了相同的異步通信方式;(2)當(dāng)檢測(cè)出有信號(hào)或中斷請(qǐng)求時(shí),都暫停正在執(zhí)行的程序而轉(zhuǎn)去執(zhí)行相應(yīng)的處理程序;
35、(3)都在處理完畢后返回到原來的斷點(diǎn);(4)對(duì)信號(hào)或中斷都可進(jìn)行屏蔽。信號(hào)與中斷的區(qū)別:(1)中斷有優(yōu)先級(jí),而信號(hào)沒有優(yōu)先級(jí),所有的信號(hào)都是平等的;(2)信號(hào)處理程序是在用戶態(tài)下運(yùn)行的,而中斷處理程序是在核心態(tài)下運(yùn)行;(3)中斷響應(yīng)是及時(shí)的,而信號(hào)響應(yīng)通常都有較大的時(shí)間延遲。信號(hào)機(jī)制具有以下三方面的功能:(1)發(fā)送信號(hào)。發(fā)送信號(hào)的程序用系統(tǒng)調(diào)用kill()實(shí)現(xiàn);(2)預(yù)置對(duì)信號(hào)的處理方式。接收信號(hào)的程序用signal()來實(shí)現(xiàn)對(duì)處理方式的預(yù)置;(3)收受信號(hào)的進(jìn)程按事先的規(guī)定完成對(duì)相應(yīng)事件的處理。2、信號(hào)的發(fā)送信號(hào)的發(fā)送,是指由發(fā)送進(jìn)程把信號(hào)送到指定進(jìn)程的信號(hào)域的某一位上。如果目標(biāo)進(jìn)程正在一個(gè)
36、可被中斷的優(yōu)先級(jí)上睡眠,核心便將它喚醒,發(fā)送進(jìn)程就此結(jié)束。一個(gè)進(jìn)程可能在其信號(hào)域中有多個(gè)位被置位,代表有多種類型的信號(hào)到達(dá),但對(duì)于一類信號(hào),進(jìn)程卻只能記住其中的某一個(gè)。進(jìn)程用kill()向一個(gè)進(jìn)程或一組進(jìn)程發(fā)送一個(gè)信號(hào)。3、對(duì)信號(hào)的處理當(dāng)一個(gè)進(jìn)程要進(jìn)入或退出一個(gè)低優(yōu)先級(jí)睡眠狀態(tài)時(shí),或一個(gè)進(jìn)程即將從核心態(tài)返回用戶態(tài)時(shí),核心都要檢查該進(jìn)程是否已收到軟中斷。當(dāng)進(jìn)程處于核心態(tài)時(shí),即使收到軟中斷也不予理睬;只有當(dāng)它返回到用戶態(tài)后,才處理軟中斷信號(hào)。對(duì)軟中斷信號(hào)的處理分三種情況進(jìn)行:(1)如果進(jìn)程收到的軟中斷是一個(gè)已決定要忽略的信號(hào)(function=1),進(jìn)程不做任何處理便立即返回;(2)進(jìn)程收到軟中斷
37、后便退出(function=0);(3)執(zhí)行用戶設(shè)置的軟中斷處理程序。二、所涉及的中斷調(diào)用1、kill()系統(tǒng)調(diào)用格式intkill(pid,sig)參數(shù)定義intpid,sig;其中,pid是一個(gè)或一組進(jìn)程的標(biāo)識(shí)符,參數(shù)sig是要發(fā)送的軟中斷信號(hào)。(1)pid0時(shí),核心將信號(hào)發(fā)送給進(jìn)程pid。(2)pid=0時(shí),核心將信號(hào)發(fā)送給與發(fā)送進(jìn)程同組的所有進(jìn)程。(3)pid=-1時(shí),核心將信號(hào)發(fā)送給所有用戶標(biāo)識(shí)符真正等于發(fā)送進(jìn)程的有效用戶標(biāo)識(shí)號(hào)的進(jìn)程。2、signal()預(yù)置對(duì)信號(hào)的處理方式,允許調(diào)用進(jìn)程控制軟中斷信號(hào)。系統(tǒng)調(diào)用格式signal(sig,function)頭文件為#include參數(shù)
38、定義signal(sig,function)intsig;void(*func)()其中sig用于指定信號(hào)的類型,sig為0則表示沒有收到任何信號(hào),余者如下表:值名字說明01SIGHUP掛起(hangup)02SIGINT中斷,當(dāng)用戶從鍵盤按c鍵或break鍵時(shí)03SIGQUIT退出,當(dāng)用戶從鍵盤按quit鍵時(shí)04SIGILL非法指令05SIGTRAP跟蹤陷阱(tracetrap),啟動(dòng)進(jìn)程,跟蹤代碼的執(zhí)行06SIGIOTIOT指令07SIGEMTEMT指令08SIGFPE浮點(diǎn)運(yùn)算溢出09SIGKILL殺死、終止進(jìn)程10SIGBUS總線錯(cuò)誤11SIGSEGV段違例(segmentationvi
39、olation),進(jìn)程試圖去訪問其虛地址空間以外的位置12SIGSYS系統(tǒng)調(diào)用中參數(shù)錯(cuò),如系統(tǒng)調(diào)用號(hào)非法13SIGPIPE向某個(gè)非讀管道中寫入數(shù)據(jù)14SIGALRM鬧鐘。當(dāng)某進(jìn)程希望在某時(shí)間后接收信號(hào)時(shí)發(fā)此信號(hào)15SIGTERM軟件終止(softwaretermination)16SIGUSR1用戶自定義信號(hào)117SIGUSR2用戶自定義信號(hào)218SIGCLD某個(gè)子進(jìn)程死19SIGPWR電源故障function:在該進(jìn)程中的一個(gè)函數(shù)地址,在核心返回用戶態(tài)時(shí),它以軟中斷信號(hào)的序號(hào)作為參數(shù)調(diào)用該函數(shù),對(duì)除了信號(hào)SIGKILL,SIGTRAP和SIGPWR以外的信號(hào),核心自動(dòng)地重新設(shè)置軟中斷信號(hào)處理
40、程序的值為SIG_DFL,一個(gè)進(jìn)程不能捕獲SIGKILL信號(hào)。function的解釋如下:(1)function=1時(shí),進(jìn)程對(duì)sig類信號(hào)不予理睬,亦即屏蔽了該類信號(hào);(2)function=0時(shí),缺省值,進(jìn)程在收到sig信號(hào)后應(yīng)終止自己;(3)function為非0,非1類整數(shù)時(shí),function的值即作為信號(hào)處理程序的指針。三、參考程序#include#include#includevoidwaiting(),stop();intwait_mark;main()intp1,p2,stdout;while(p1=fork()=-1);/*創(chuàng)建子進(jìn)程p1*/if(p10)while(p2=fo
41、rk()=-1);/*創(chuàng)建子進(jìn)程p2*/if(p20)wait_mark=1;signal(SIGINT,stop);/*接收到c信號(hào),轉(zhuǎn)stop*/waiting();kill(p1,16);/*向p1發(fā)軟中斷信號(hào)16*/kill(p2,17);/*向p2發(fā)軟中斷信號(hào)17*/wait(0);/*同步*/wait(0);printf(Parentprocessiskilled!n);exit(0);elsewait_mark=1;signal(17,stop);/*接收到軟中斷信號(hào)17,轉(zhuǎn)stop*/waiting();lockf(stdout,1,0);printf(Childprocess
42、2iskilledbyparent!n);lockf(stdout,0,0);exit(0);elsewait_mark=1;signal(16,stop);/*接收到軟中斷信號(hào)16,轉(zhuǎn)stop*/waiting();lockf(stdout,1,0);printf(Childprocess1iskilledbyparent!n);lockf(stdout,0,0);exit(0);voidwaiting()while(wait_mark!=0);voidstop()wait_mark=0;四、運(yùn)行結(jié)果屏幕上無反應(yīng),按下C后,顯示Parentprocessiskilled!五、分析原因上述程序
43、中,signal()都放在一段程序的前面部位,而不是在其他接收信號(hào)處。這是因?yàn)閟ignal()的執(zhí)行只是為進(jìn)程指定信號(hào)值16或17的作用,以及分配相應(yīng)的與stop()過程鏈接的指針。因而,signal()函數(shù)必須在程序前面部分執(zhí)行。本方法通信效率低,當(dāng)通信數(shù)據(jù)量較大時(shí)一般不用此法。六、思考1、該程序段前面部分用了兩個(gè)wait(0),它們起什么作用?2、該程序段中每個(gè)進(jìn)程退出時(shí)都用了語句exit(0),為什么?3、為何預(yù)期的結(jié)果并未顯示出?4、程序該如何修改才能得到正確結(jié)果?5、不修改程序如何得到期望的輸出?實(shí)驗(yàn)三進(jìn)程通信(二)進(jìn)程的管道通信實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、了解什么是管道2、熟悉UNIX/LIN
44、UX支持的管道通信方式實(shí)驗(yàn)內(nèi)容編寫程序?qū)崿F(xiàn)進(jìn)程的管道通信。用系統(tǒng)調(diào)用pipe()建立一管道,二個(gè)子進(jìn)程P1和P2分別向管道各寫一句話:Child1issendingamessage!Child2issendingamessage!父進(jìn)程從管道中讀出二個(gè)來自子進(jìn)程的信息并顯示(要求先接收P1,后P2)。實(shí)驗(yàn)指導(dǎo)一、什么是管道UNIX系統(tǒng)在OS的發(fā)展上,最重要的貢獻(xiàn)之一便是該系統(tǒng)首創(chuàng)了管道(pipe)。這也是UNIX系統(tǒng)的一大特色。所謂管道,是指能夠連接一個(gè)寫進(jìn)程和一個(gè)讀進(jìn)程的、并允許它們以生產(chǎn)者消費(fèi)者方式進(jìn)行通信的一個(gè)共享文件,又稱為pipe文件。由寫進(jìn)程從管道的寫入端(句柄1)將數(shù)據(jù)寫入管道,
45、而讀進(jìn)程則從管道的讀出端(句柄0)讀出數(shù)據(jù)。句柄fd0句柄fd1讀出端寫入端二、管道的類型:1、有名管道一個(gè)可以在文件系統(tǒng)中長(zhǎng)期存在的、具有路徑名的文件。用系統(tǒng)調(diào)用mknod()建立。它克服無名管道使用上的局限性,可讓更多的進(jìn)程也能利用管道進(jìn)行通信。因而其它進(jìn)程可以知道它的存在,并能利用路徑名來訪問該文件。對(duì)有名管道的訪問方式與訪問其他文件一樣,需先用open()打開。2、無名管道一個(gè)臨時(shí)文件。利用pipe()建立起來的無名文件(無路徑名)。只用該系統(tǒng)調(diào)用所返回的文件描述符來標(biāo)識(shí)該文件,故只有調(diào)用pipe()的進(jìn)程及其子孫進(jìn)程才能識(shí)別此文件描述符,才能利用該文件(管道)進(jìn)行通信。當(dāng)這些進(jìn)程不再
46、使用此管道時(shí),核心收回其索引結(jié)點(diǎn)。二種管道的讀寫方式是相同的,本文只講無名管道。3、pipe文件的建立分配磁盤和內(nèi)存索引結(jié)點(diǎn)、為讀進(jìn)程分配文件表項(xiàng)、為寫進(jìn)程分配文件表項(xiàng)、分配用戶文件描述符4、讀/寫進(jìn)程互斥內(nèi)核為地址設(shè)置一個(gè)讀指針和一個(gè)寫指針,按先進(jìn)先出順序讀、寫。為使讀、寫進(jìn)程互斥地訪問pipe文件,需使各進(jìn)程互斥地訪問pipe文件索引結(jié)點(diǎn)中的直接地址項(xiàng)。因此,每次進(jìn)程在訪問pipe文件前,都需檢查該索引文件是否已被上鎖。若是,進(jìn)程便睡眠等待,否則,將其上鎖,進(jìn)行讀/寫。操作結(jié)束后解鎖,并喚醒因該索引結(jié)點(diǎn)上鎖而睡眠的進(jìn)程。三、所涉及的系統(tǒng)調(diào)用1、pipe()建立一無名管道。系統(tǒng)調(diào)用格式pip
47、e(filedes)參數(shù)定義intpipe(filedes);intfiledes2;其中,filedes1是寫入端,filedes0是讀出端。該函數(shù)使用頭文件如下:#include#inlcude#include2、read()系統(tǒng)調(diào)用格式read(fd,buf,nbyte)功能:從fd所指示的文件中讀出nbyte個(gè)字節(jié)的數(shù)據(jù),并將它們送至由指針buf所指示的緩沖區(qū)中。如該文件被加鎖,等待,直到鎖打開為止。參數(shù)定義intread(fd,buf,nbyte);intfd;char*buf;unsignednbyte;3、write()系統(tǒng)調(diào)用格式read(fd,buf,nbyte)功能:把nb
48、yte個(gè)字節(jié)的數(shù)據(jù),從buf所指向的緩沖區(qū)寫到由fd所指向的文件中。如文件加鎖,暫停寫入,直至開鎖。參數(shù)定義同read()。四、參考程序#include#include#includeintpid1,pid2;main()intfd2;charoutpipe100,inpipe100;pipe(fd);/*創(chuàng)建一個(gè)管道*/while(pid1=fork()=-1);if(pid1=0)lockf(fd1,1,0);sprintf(outpipe,child1processissendingmessage!);/*把串放入數(shù)組outpipe中*/write(fd1,outpipe,50);/*向
49、管道寫長(zhǎng)為50字節(jié)的串*/sleep(5);/*自我阻塞5秒*/lockf(fd1,0,0);exit(0);elsewhile(pid2=fork()=-1);if(pid2=0)lockf(fd1,1,0);/*互斥*/sprintf(outpipe,child2processissendingmessage!);write(fd1,outpipe,50);sleep(5);lockf(fd1,0,0);exit(0);elsewait(0);/*同步*/read(fd0,inpipe,50);/*從管道中讀長(zhǎng)為50字節(jié)的串*/printf(%sn,inpipe);wait(0);read
50、(fd0,inpipe,50);printf(%sn,inpipe);exit(0);五、運(yùn)行結(jié)果延遲5秒后顯示child1processissendingmessage!再延遲5秒child2processissendingmessage!六、思考題1、程序中的sleep(5)起什么作用?2、子進(jìn)程1和2為什么也能對(duì)管道進(jìn)行操作?實(shí)驗(yàn)三進(jìn)程通信(三)消息的發(fā)送與接收實(shí)驗(yàn)實(shí)驗(yàn)?zāi)康?、了解什么是消息2、熟悉消息傳送的機(jī)理實(shí)驗(yàn)內(nèi)容消息的創(chuàng)建、發(fā)送和接收。使用系統(tǒng)調(diào)用msgget(),msgsnd(),msgrev(),及msgctl()編制一長(zhǎng)度為k的消息發(fā)送和接收的程序。實(shí)驗(yàn)指導(dǎo)一、什么是消息消
51、息(message)是一個(gè)格式化的可變長(zhǎng)的信息單元。消息機(jī)制允許由一個(gè)進(jìn)程給其它任意的進(jìn)程發(fā)送一個(gè)消息。當(dāng)一個(gè)進(jìn)程收到多個(gè)消息時(shí),可將它們排成一個(gè)消息隊(duì)列。消息使用二種重要的數(shù)據(jù)結(jié)構(gòu):一是消息首部,其中記錄了一些與消息有關(guān)的信息,如消息數(shù)據(jù)的字節(jié)數(shù);二個(gè)消息隊(duì)列頭表,其每一表項(xiàng)是作為一個(gè)消息隊(duì)列的消息頭,記錄了消息隊(duì)列的有關(guān)信息。1、消息機(jī)制的數(shù)據(jù)結(jié)構(gòu)(1)消息首部記錄一些與消息有關(guān)的信息,如消息的類型、大小、指向消息數(shù)據(jù)區(qū)的指針、消息隊(duì)列的鏈接指針等。(2)消息隊(duì)列頭表其每一項(xiàng)作為一個(gè)消息隊(duì)列的消息頭,記錄了消息隊(duì)列的有關(guān)信息如指向消息隊(duì)列中第一個(gè)消息和指向最后一個(gè)消息的指針、隊(duì)列中消息的數(shù)
52、目、隊(duì)列中消息數(shù)據(jù)的總字節(jié)數(shù)、隊(duì)列所允許消息數(shù)據(jù)的最大字節(jié)總數(shù),還有最近一次執(zhí)行發(fā)送操作的進(jìn)程標(biāo)識(shí)符和時(shí)間、最近一次執(zhí)行接收操作的進(jìn)程標(biāo)識(shí)符和時(shí)間等。2、消息隊(duì)列的描述符UNIX中,每一個(gè)消息隊(duì)列都有一個(gè)稱為關(guān)鍵字(key)的名字,是由用戶指定的;消息隊(duì)列有一消息隊(duì)列描述符,其作用與用戶文件描述符一樣,也是為了方便用戶和系統(tǒng)對(duì)消息隊(duì)列的訪問。二、涉及的系統(tǒng)調(diào)用1.msgget()創(chuàng)建一個(gè)消息,獲得一個(gè)消息的描述符。核心將搜索消息隊(duì)列頭表,確定是否有指定名字的消息隊(duì)列。若無,核心將分配一新的消息隊(duì)列頭,并對(duì)它進(jìn)行初始化,然后給用戶返回一個(gè)消息隊(duì)列描述符,否則它只是檢查消息隊(duì)列的許可權(quán)便返回。系統(tǒng)
53、調(diào)用格式:msgqid=msgget(key,flag)該函數(shù)使用頭文件如下:#include#include#include參數(shù)定義intmsgget(key,flag)key_tkey;intflag;其中:key是用戶指定的消息隊(duì)列的名字;flag是用戶設(shè)置的標(biāo)志和訪問方式。如IPC_CREAT|0400是否該隊(duì)列已被創(chuàng)建。無則創(chuàng)建,是則打開;IPC_EXCL|0400是否該隊(duì)列的創(chuàng)建應(yīng)是互斥的。msgqid是該系統(tǒng)調(diào)用返回的描述符,失敗則返回-1。2.msgsnd()發(fā)送一消息。向指定的消息隊(duì)列發(fā)送一個(gè)消息,并將該消息鏈接到該消息隊(duì)列的尾部。系統(tǒng)調(diào)用格式:msgsnd(msgqid,msgp,size,flag)該函數(shù)使用頭文件如下:#include#include#include參數(shù)定義:int
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 整車配套業(yè)務(wù)方案
- 購(gòu)紅土協(xié)議書范本
- 校區(qū)支部共建方案(3篇)
- 住房節(jié)能改造方案
- 鄉(xiāng)村閑置房流轉(zhuǎn)方案
- 電廠續(xù)建項(xiàng)目方案(3篇)
- 流媒體協(xié)議書范本
- 買賣轉(zhuǎn)讓協(xié)議書范本格式
- 木房建筑改造方案
- 提前股權(quán)回購(gòu)協(xié)議書范本
- 2025江蘇省招聘村級(jí)后備干部考試題(含答案)
- 相控陣超聲檢測(cè)技術(shù)及應(yīng)用
- 弘揚(yáng)教育家精神做新時(shí)代大學(xué)教師
- 生態(tài)環(huán)境執(zhí)法案件培訓(xùn)
- 2026年高考政治一輪復(fù)習(xí):高考政治命題備考策略
- 2024年湖南省辰溪縣檔案局公開招聘試題帶答案
- 鋰離子電池安全性能優(yōu)化:針刺實(shí)驗(yàn)與失效機(jī)制分析
- 2025至2030年中國(guó)森林消防車行業(yè)市場(chǎng)全景評(píng)估及未來趨勢(shì)研判報(bào)告
- 2025陜西延長(zhǎng)石油集團(tuán)所屬單位內(nèi)部遴選筆試參考題庫附帶答案詳解
- 2025生產(chǎn)與運(yùn)作管理試題及答案
- 暑假的一次冒險(xiǎn)經(jīng)歷記事作文4篇范文
評(píng)論
0/150
提交評(píng)論