linux進(jìn)程創(chuàng)建和通信.ppt_第1頁(yè)
linux進(jìn)程創(chuàng)建和通信.ppt_第2頁(yè)
linux進(jìn)程創(chuàng)建和通信.ppt_第3頁(yè)
linux進(jìn)程創(chuàng)建和通信.ppt_第4頁(yè)
linux進(jìn)程創(chuàng)建和通信.ppt_第5頁(yè)
已閱讀5頁(yè),還剩62頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、 Linux 進(jìn)程控制及進(jìn)程間通信 Email:SummaryLinux進(jìn)程創(chuàng)建、撤銷Linux進(jìn)程間的通信Linux進(jìn)程創(chuàng)建、撤銷Linux進(jìn)程控制包括的內(nèi)容:進(jìn)程創(chuàng)建、進(jìn)程撤銷進(jìn)程睡眠、進(jìn)程喚醒Linux進(jìn)程創(chuàng)建、撤銷Linux進(jìn)程的族親關(guān)系Linux進(jìn)程之間不是孤立存在的,它們之間有一定的族親關(guān)系。進(jìn)程1進(jìn)程2父進(jìn)程子進(jìn)程產(chǎn) 生Linux進(jìn)程創(chuàng)建子進(jìn)程1與子進(jìn)程2構(gòu)成兄弟進(jìn)程。(按照創(chuàng)建時(shí)間確定,先者為兄,后者為弟); 父進(jìn)程子進(jìn)程1子進(jìn)程2Linux進(jìn)程創(chuàng)建Linux系統(tǒng)的進(jìn)程樹(shù)init進(jìn)程A進(jìn)程B進(jìn)程C進(jìn)程D進(jìn)程E進(jìn)程F系統(tǒng)加電啟動(dòng)后,系統(tǒng)中只有一個(gè)進(jìn)程初始化進(jìn)程,又稱init進(jìn)程(

2、對(duì)應(yīng)的結(jié)構(gòu)體init_task)。Init進(jìn)程是所有進(jìn)程的祖先進(jìn)程,它的進(jìn)程pid=1Linux進(jìn)程創(chuàng)建Linux進(jìn)程的創(chuàng)建在linux中除了init進(jìn)程是由系統(tǒng)啟動(dòng)時(shí)創(chuàng)建的外,其他所有進(jìn)程都是由當(dāng)前進(jìn)程使用系統(tǒng)調(diào)用fork()創(chuàng)建的。進(jìn)程創(chuàng)建后父子進(jìn)程在系統(tǒng)中并發(fā)執(zhí)行。Linux進(jìn)程創(chuàng)建的重要特點(diǎn):Linux對(duì)子進(jìn)程繼承父進(jìn)程的虛擬存儲(chǔ)空間有獨(dú)特的處理方法:它把所謂的繼承當(dāng)作共享來(lái)處理 。所謂共享指子進(jìn)程在創(chuàng)建時(shí)并不建立虛擬內(nèi)存空間,而是子進(jìn)程與父進(jìn)程共享父進(jìn)程的虛擬內(nèi)存空間。即:子進(jìn)程在創(chuàng)建后共享父進(jìn)程的虛存空間,所以子進(jìn)程在剛創(chuàng)建時(shí)使用的是父進(jìn)程的代碼段、數(shù)據(jù)段。即子進(jìn)程在創(chuàng)建后執(zhí)行的時(shí)

3、父進(jìn)程的程序代碼。Linux進(jìn)程創(chuàng)建”寫時(shí)拷貝“技術(shù)子進(jìn)程在何時(shí)如何建立自己的虛擬內(nèi)存空間?只有在兩個(gè)進(jìn)程中某個(gè)進(jìn)程要向虛擬內(nèi)存寫入時(shí),才建立子進(jìn)程自己的虛擬內(nèi)存空間,并把原來(lái)虛擬內(nèi)存空間的內(nèi)容拷貝到新建立的虛擬內(nèi)存區(qū)域中,然后在新建的虛擬內(nèi)存空間寫入信息.Linux進(jìn)程創(chuàng)建Fork()系統(tǒng)調(diào)用父進(jìn)程創(chuàng)建子進(jìn)程是通過(guò) fork()系統(tǒng)調(diào)用完成的。此時(shí)一個(gè)進(jìn)程“分裂”成兩個(gè)進(jìn)程:一個(gè)是原來(lái)的進(jìn)程,一個(gè)是新創(chuàng)建的進(jìn)程。通過(guò)fork()返回值區(qū)分父子進(jìn)程:對(duì)父進(jìn)程而言,返回的是子進(jìn)程的PID對(duì)子進(jìn)程而言,返回的是0Linux進(jìn)程創(chuàng)建在語(yǔ)句val=fork()之前,只有一個(gè)進(jìn)程在執(zhí)行這段代碼,但在這條

4、語(yǔ)句之后,就變成兩個(gè)進(jìn)程在執(zhí)行了,這兩個(gè)進(jìn)程的代碼部分完全相同。兩個(gè)進(jìn)程中,原先就存在的那個(gè)被稱作“父進(jìn)程”,新出現(xiàn)的那個(gè)被稱作“子進(jìn)程”。父子進(jìn)程的區(qū)別除了進(jìn)程標(biāo)志符(process ID)不同外,變量pid的值也不相同,pid存放的是fork的返回值。fork調(diào)用的一個(gè)奇妙之處就是它僅僅被調(diào)用一次,卻能夠返回兩次,它可能有三種不同的返回值:在父進(jìn)程中,fork返回新創(chuàng)建子進(jìn)程的進(jìn)程ID;在子進(jìn)程中,fork返回0;如果出現(xiàn)錯(cuò)誤,fork返回一個(gè)負(fù)值;Linux進(jìn)程創(chuàng)建舉例:#include#includemain() pid_t val; printf(PID before fork():

5、%dn,(int)getpid(); if(val=fork()printf(parent process PID:%dn,(int)getpid(); elseprintf(child process PID:%dn,(int)getpid();執(zhí)行結(jié)果PID before fork():490parent process PID:490child process PID:491Linux子進(jìn)程的執(zhí)行子進(jìn)程的執(zhí)行創(chuàng)建進(jìn)程的目的是需要該進(jìn)程完成一定的任務(wù),執(zhí)行它的程序代碼。Linux中,使程序執(zhí)行的唯一方法是使用系統(tǒng)調(diào)用exec()Exec()函數(shù)族#include int execl(con

6、st char *path, const char *arg, .);int execlp(const char *file, const char *arg, .); int execle(const char *path, const char *arg, ., char *const envp);int execv(const char *path, char *const argv); int execvp(const char *file, char *const argv);int execve(const char *path, char *const argv, char *c

7、onst envp); Linux進(jìn)程創(chuàng)建int execl(const char *path, const char *arg, .);Path指出了要執(zhí)行的程序的完整路徑Arg0表示要執(zhí)行的文件名或命令名Arg1.argn表示可執(zhí)行文件或命令需要的參數(shù)#includevoid main() if(fork() printf(“this is the parent process!n”); else execl(“/bin/ls”,”ls”,”-l”,0); return;舉例:Linux進(jìn)程終止和撤銷Linux進(jìn)程終止exit()終止的兩種情況:正常終止 :完成本身任務(wù)而終止,調(diào)用exit

8、()或運(yùn)行到最后而終止被內(nèi)核強(qiáng)制終止:運(yùn)行中出現(xiàn)了致命錯(cuò)誤。終止的進(jìn)程占有部分系統(tǒng)資源,必須撤銷它們exit()往往會(huì)帶有參數(shù),如exit(0)表示正常退出,非零表示不正常退出。終止的進(jìn)程狀態(tài)為TASK_ZOMBIE系統(tǒng)調(diào)用exit,它的作用是使進(jìn)程退出,但也僅僅限于將一個(gè)正常的進(jìn)程變成一個(gè)僵尸進(jìn)程,并不能將其完全銷毀僵尸進(jìn)程中保存著很多對(duì)程序員和系統(tǒng)管理員非常重要的信息,首先,這個(gè)進(jìn)程是怎么死亡的?是正常退出呢,還是出現(xiàn)了錯(cuò)誤,還是被其它進(jìn)程強(qiáng)迫退出的?其次,這個(gè)進(jìn)程占用的總系統(tǒng)CPU時(shí)間和總用戶CPU時(shí)間分別是多少?發(fā)生頁(yè)錯(cuò)誤的數(shù)目和收到信號(hào)的數(shù)目。這些信息都被存儲(chǔ)在僵尸進(jìn)程中,Linux

9、進(jìn)程終止和撤銷進(jìn)程的撤銷release()一個(gè)進(jìn)程終止后不能自己撤銷自己,而只能由他的父進(jìn)程或祖先進(jìn)程撤銷它。父進(jìn)程建立子進(jìn)程后,使用wait()系統(tǒng)調(diào)用等待子進(jìn)程終止,當(dāng)檢查到子進(jìn)程的狀態(tài)是僵死態(tài)時(shí),撤銷子進(jìn)程,調(diào)用release()函數(shù),釋放僵死進(jìn)程的描述符如果父進(jìn)程早子進(jìn)程終止,為了使子進(jìn)程不成為孤立進(jìn)程,內(nèi)核將這些子進(jìn)程賦予init進(jìn)程,使init進(jìn)程成為它們的父進(jìn)程,它們的撤銷也由init進(jìn)程完成。wait的函數(shù)原型是:#include #include pid_t wait(int *status) 進(jìn)程一旦調(diào)用了wait,就立即阻塞自己,由wait自動(dòng)分析是否當(dāng)前進(jìn)程的某個(gè)子進(jìn)程

10、已經(jīng)退出,如果讓它找到了這樣一個(gè)已經(jīng)變成僵尸的子進(jìn)程,wait就會(huì)收集這個(gè)子進(jìn)程的信息,并把它徹底銷毀后返回;如果沒(méi)有找到這樣一個(gè)子進(jìn)程,wait就會(huì)一直阻塞在這里,直到有一個(gè)出現(xiàn)為止。參數(shù)status用來(lái)保存被收集進(jìn)程退出時(shí)的一些狀態(tài),它是一個(gè)指向int類型的指針。如果成功,wait會(huì)返回被收集的子進(jìn)程的進(jìn)程IDwaitpid:pid_t waitpid(pid_t pid,int *status,int options)系統(tǒng)調(diào)用waitpid和wait的作用是完全相同的,但waitpid多出了兩個(gè)可由用戶控制的參數(shù)pid和options,從而為我們編程提供了另一種更靈活的方式 。當(dāng)pid取

11、不同的值時(shí),在這里有不同的意義。1.pid0時(shí),只等待進(jìn)程ID等于pid的子進(jìn)程,不管其它已經(jīng)有多少子進(jìn)程運(yùn)行結(jié)束退出了,只要指定的子進(jìn)程還沒(méi)有結(jié)束,waitpid就會(huì)一直等下去。2.pid=-1時(shí),等待任何一個(gè)子進(jìn)程退出,沒(méi)有任何限制,此時(shí)waitpid和wait的作用一模一樣。3.pid=0時(shí),等待同一個(gè)進(jìn)程組中的任何子進(jìn)程,如果子進(jìn)程已經(jīng)加入了別的進(jìn)程組,waitpid不會(huì)對(duì)它做任何理睬。4.pid-1時(shí),等待一個(gè)指定進(jìn)程組中的任何子進(jìn)程,這個(gè)進(jìn)程組的ID等于pid的絕對(duì)值。options參數(shù)目前在Linux中只支持WNOHANG和WUNTRACED兩個(gè)選項(xiàng)如果我們不想使用它們,也可以把

12、options設(shè)為0進(jìn)程通信進(jìn)程通信:進(jìn)程間信息交換。低級(jí)通信機(jī)制:信息量小,如pv操作。高級(jí)通信機(jī)制:信息量大。高級(jí)通信方式:消息通信機(jī)制(直接通信、信箱通信)共享內(nèi)存管道信號(hào)Linux進(jìn)程間通信在Linux系統(tǒng)中,以進(jìn)程為單位分配和管理資源。由于保護(hù)的緣故,一個(gè)進(jìn)程不能直接訪問(wèn)另一個(gè)進(jìn)程的資源,也就是說(shuō),進(jìn)程之間互相封閉 信號(hào):信號(hào)每次只能傳遞一個(gè)數(shù)據(jù); linux管道:管道只能在兩個(gè)進(jìn)程間單向交換信息 ;IPC(Internal Process Communication)消息隊(duì)列 IPC共享內(nèi)存IPC信號(hào)量機(jī)制Linux進(jìn)程間通信管道機(jī)制管道機(jī)制 管道是Linux的一種最簡(jiǎn)單的通信機(jī)制

13、。管道的概念: 管道機(jī)制是一個(gè)數(shù)據(jù)的邏輯“通道” 。管道寫進(jìn)程讀進(jìn)程Linux把管道當(dāng)作是一種文件,采用文件管理的辦法管理管道。管道與文件的區(qū)別在于 ,管道不使用外存,而是使用內(nèi)存存放傳送的數(shù)據(jù)Linux進(jìn)程間通信管道機(jī)制管道特點(diǎn) 傳送方向固定的單向管道,一個(gè)管道的數(shù)據(jù)只能向一個(gè)方向傳送,并且管道一旦確定了其數(shù)據(jù)傳送方向后就不能再更改。數(shù)據(jù)在管道中以字符流的形態(tài)傳送的,即以字節(jié)為單位的順序數(shù)據(jù)(FIFO方式)管道分類有名管道無(wú)名管道區(qū)別無(wú)名管道只能在父子進(jìn)程之間通信,有名管道可以在任意進(jìn)程間通信無(wú)名管道沒(méi)有名字標(biāo)識(shí),有名管道有名稱。Linux進(jìn)程間通信管道機(jī)制無(wú)名管道:無(wú)名管道的系統(tǒng)調(diào)用:#i

14、nclude int pipe(int pipe2)參數(shù)是2個(gè)元素的int型數(shù)組,pipe0是讀取管道的文件標(biāo)識(shí)符,pipe1是寫入管道的文件標(biāo)識(shí)符Linux進(jìn)程間通信管道機(jī)制用法: 用于親緣關(guān)系的進(jìn)程間的通信,主要用于父子進(jìn)程間的通信。*先建立管道再建立子進(jìn)程的順序若不然,先建立子進(jìn)程,再建立管道,管道只對(duì)建立它的進(jìn)程可見(jiàn),對(duì)另一個(gè)進(jìn)程是看不見(jiàn)的,因此無(wú)法實(shí)現(xiàn)父子間的通信。確定管道通信的方向(單向通信)管道Pipe1Pipe0Linux進(jìn)程間通信管道機(jī)制舉例:在該例中,父進(jìn)程建立管道后創(chuàng)建一個(gè)子進(jìn)程。子進(jìn)程的任務(wù)是把一組字符串信息寫入管道,父進(jìn)程在子進(jìn)程完成任務(wù)終止后,從管道中讀取信息并顯示

15、在顯示器上。 Linux進(jìn)程間通信管道機(jī)制有名管道 無(wú)名管道只能在父子進(jìn)程間通信,為了解決這個(gè)問(wèn)題,linux提供了有名管道。有名管道的系統(tǒng)調(diào)用#include Int mkfifo(const char *path,mode_t mode)參數(shù)說(shuō)明:Path:要使用的命名管道的路徑和名字Mode指明管道的訪問(wèn)權(quán)限返回值:成功返回值0;否則返回負(fù)數(shù);Linux進(jìn)程間通信管道機(jī)制舉例例:有兩個(gè)程序,其中一個(gè)程序把一組信息寫入管道,另一個(gè)程序把管道中的信息讀出后顯示在屏幕上。uLinux進(jìn)程間通信IPC共享內(nèi)存共向內(nèi)存是進(jìn)程間通信速度最快的一種。思想:允許多個(gè)進(jìn)程訪問(wèn)同一個(gè)內(nèi)存區(qū)域?qū)嵭羞M(jìn)程之間的數(shù)

16、據(jù)傳送多任務(wù)操作系統(tǒng)不允許用戶進(jìn)程直接訪問(wèn)物理內(nèi)存,即物理內(nèi)存對(duì)用戶進(jìn)程不可見(jiàn)。每個(gè)進(jìn)程只能看見(jiàn)自己的虛擬內(nèi)存空間Linux采用內(nèi)存映射技術(shù)把共享內(nèi)存區(qū)域映射到有關(guān)進(jìn)程的虛擬內(nèi)存空間,使他成為進(jìn)程虛擬內(nèi)存的一部分,從而進(jìn)程可以對(duì)這部分虛擬內(nèi)存區(qū)域進(jìn)行讀寫。進(jìn)程與共享內(nèi)存的結(jié)合;共享內(nèi)存映射到進(jìn)程虛擬區(qū)域的過(guò)程進(jìn)程與虛擬內(nèi)存的分離;當(dāng)使用共享內(nèi)存完成數(shù)據(jù)交換后需要釋放相關(guān)的虛擬內(nèi)存區(qū)域,即脫離與共享內(nèi)存的的聯(lián)系。Linux進(jìn)程間通信IPC共享內(nèi)存共享內(nèi)存區(qū)域進(jìn)程A進(jìn)程B0 x50000 x30000 x70000 x5000Linux進(jìn)程間通信IPC共享內(nèi)存共享內(nèi)存使用標(biāo)識(shí)號(hào)來(lái)標(biāo)識(shí):共享內(nèi)存標(biāo)識(shí)

17、號(hào)shmid每個(gè)共享內(nèi)存區(qū)域由一個(gè)數(shù)據(jù)結(jié)構(gòu)記錄管理信息,稱為共享內(nèi)存描述符,稱為結(jié)構(gòu)體shmid_ds.Struct shmid_dsStruct ipc_perm shm_perm; /*訪問(wèn)權(quán)限*/Int shm_segsz;/*共享內(nèi)存大小(字節(jié))*/Time_t shm_atime;/*最近一次結(jié)合時(shí)間*/Time_t shm_dtime;/*最近一次分離時(shí)間*/Time_t shm_ctime;/*最近一次修改時(shí)間*/Unsigned short shm_cpid;/*創(chuàng)建者pid*/Unsigned short shm_lpid;/*最后一次對(duì)共享內(nèi)存進(jìn)行操作的進(jìn)程的pid*/Sh

18、ort shm_nattch;/*當(dāng)前結(jié)合進(jìn)程的數(shù)量*/Unsigned short shm_npages;/*共享內(nèi)存使用的頁(yè)面數(shù)*/Unsigned long shm_pages;/*共享內(nèi)存頁(yè)表指針*/Struct vm_area_struct *attaches;/*供結(jié)合進(jìn)程使用的虛擬內(nèi)存描述符*/Linux進(jìn)程間通信IPC共享內(nèi)存Linux進(jìn)程間通信IPC共享內(nèi)存共享內(nèi)存的生成與控制共享內(nèi)存的創(chuàng)建shmflg與消息隊(duì)列的flag一樣函數(shù)返回共享內(nèi)存標(biāo)識(shí)符shmidInt shmget(key_t key,int size,int shmflg)Linux進(jìn)程間通信IPC對(duì)象管理的一

19、個(gè)重要特點(diǎn)是,系統(tǒng)使用一個(gè)鍵值和一個(gè)標(biāo)識(shí)號(hào)來(lái)識(shí)別每個(gè)IPC對(duì)象。鍵值和標(biāo)識(shí)號(hào)是唯一的,而且是一一對(duì)應(yīng)的標(biāo)識(shí)號(hào)是進(jìn)程運(yùn)行過(guò)程中動(dòng)態(tài)產(chǎn)生的,進(jìn)程之間相互獨(dú)立,那么該標(biāo)識(shí)號(hào)對(duì)其它進(jìn)程不可見(jiàn)。無(wú)法完成進(jìn)程間的通信。Key作為一個(gè)靜態(tài)的識(shí)別值,它獨(dú)立于所有進(jìn)程,但對(duì)所有進(jìn)程可見(jiàn)。為什么使用兩種標(biāo)識(shí)方法:KeyLinux進(jìn)程間通信Key鍵值的生成:使用一個(gè)文件名和一個(gè)符號(hào)調(diào)用C函數(shù)ftok()生成。Pathname:一個(gè)已經(jīng)存在的路徑和文件名proj是任意一個(gè)符號(hào)Ket_t ftok(char *pathname,char proj)公有鍵值:ftok()生成的鍵值或用戶自己指定的鍵值私有鍵值:IPC_P

20、RIVATE,它是私有的,僅在進(jìn)程及子進(jìn)程中可見(jiàn)。Linux進(jìn)程間通信Msgflg參數(shù) 指定消息隊(duì)列的訪問(wèn)權(quán)限和操作模式0400 允許創(chuàng)建者讀0200 允許創(chuàng)建者寫0040 允許創(chuàng)建者同組用戶讀0020 允許創(chuàng)建者同組用戶寫0004 允許其它進(jìn)程讀0002 允許其它進(jìn)程寫Linux進(jìn)程間通信IPC共享內(nèi)存共享內(nèi)存的控制Cmd:IPC_STAT;獲取共享內(nèi)存的管理信息,把該共享內(nèi)存的描述符內(nèi)容復(fù)制到buf指向的結(jié)構(gòu)體IPC_SET:修改共享內(nèi)存描述符內(nèi)容IPC_RMID:刪除共享內(nèi)存Shmctl(int shmid,int cmd,struct shmid_ds *buf)Linux進(jìn)程間通信I

21、PC共享內(nèi)存與共享內(nèi)存的結(jié)合Shmaddr:進(jìn)程指定的共享內(nèi)存在進(jìn)程虛存空間的起始地址,若參數(shù)為0,則由系統(tǒng)自動(dòng)分配Shmflg為SHM_RDONLY時(shí)只能對(duì)共享內(nèi)存進(jìn)行讀取操作,而不能寫入。為0時(shí),可以讀取寫入。Int shmat(int shmid,char*shmaddr,int shmflg)Linux進(jìn)程間通信IPC共享內(nèi)存與共享內(nèi)存的分離Int shmdt(char*shmaddr)Shmaddr:進(jìn)出虛擬空間中共享內(nèi)存的首地址。執(zhí)行該函數(shù)將釋放進(jìn)程虛擬空間中共享內(nèi)存占用的區(qū)域,并修改shmid_ds中的相關(guān)項(xiàng)。 Linux進(jìn)程間通信IPC共享內(nèi)存舉例:#define KEY 12

22、34 /* 鍵 */#define SIZE 1024 /* 欲建立的共享內(nèi)存的大小 */int main()int shmid;char *shmaddr;struct shmid_ds buf;shmid = shmget(KEY,SIZE,IPC_CREAT|0600); /* 建立共享內(nèi)存 */if(shmid = -1)printf(create share memory failed: %s,strerror(errno);return 0;if(fork() = 0) /* 子進(jìn)程 */* 系統(tǒng)自動(dòng)選擇一個(gè)地址連接 */shmaddr = (char *)shmat(shmid,

23、NULL,0);if(shmaddr = (void *)-1)printf(connect to the share memory failed: %s,strerror(errno);return 0;strcpy(shmaddr,hello, this is child process!n);shmdt(shmaddr); /* detach共享內(nèi)存 */return 0;else /* 父進(jìn)程 */sleep(3); /* 等待子進(jìn)程執(zhí)行完畢 */shmctl(shmid,IPC_STAT,&buf); /* 取得共享內(nèi)存的相關(guān)信息 */printf( size of the shar

24、e memory: );printf(shm_segsz = %d bytes n,buf.shm_segsz);printf( process id of the creator: );printf(shm_cpid = %d n,buf.shm_cpid);printf( process id of the last operator: );printf(shm_lpid = %d n,buf.shm_lpid);/* 系統(tǒng)自動(dòng)選擇一個(gè)地址連接 */shmaddr = (char *)shmat(shmid,NULL,0);if(shmaddr = (void *)-1)printf(co

25、nnect the share memory failed: %s,strerror(errno);return 0;printf(print the content of the share memory: );printf(%s n,shmaddr);shmdt(shmaddr); /* detach共享內(nèi)存 */* 當(dāng)不再有任何其它進(jìn)程使用該共享內(nèi)存時(shí)系統(tǒng)將自動(dòng)銷毀它 */shmctl(shmid,IPC_RMID,NULL);wait(null); Linux信號(hào)量機(jī)制Linux的信號(hào)量機(jī)制有兩種:其本身設(shè)置的信號(hào)量機(jī)制引進(jìn)UNIX SYSTEM V的IPC中的信號(hào)量機(jī)制。它更完善、更

26、方便使用。它可以一次性地對(duì)多個(gè)信號(hào)量進(jìn)行PV操作。 本節(jié)介紹后者,其涉及到的函數(shù)和數(shù)據(jù)結(jié)構(gòu)分別定義在Linux源文件的ipc/sem.c和include/linux/sem.hIPC信號(hào)量機(jī)制信號(hào)量系統(tǒng)中每個(gè)信號(hào)量對(duì)應(yīng)一個(gè)信號(hào)量結(jié)構(gòu)體sem,其定義如下:Struct semShort semval; /*信號(hào)量的值*/Unshort sempid; /*記錄對(duì)信號(hào)量最后一次實(shí)施操作進(jìn)程的PID*/(為了解決死鎖)IPC信號(hào)量機(jī)制在這方面做了改進(jìn),它可以使用原語(yǔ)一次對(duì)多個(gè)信號(hào)量進(jìn)行操作。為此,引進(jìn)了信號(hào)量集合的概念:把進(jìn)程需要訪問(wèn)資源對(duì)應(yīng)的信號(hào)量組成一個(gè)信號(hào)量集合。IPC信號(hào)量機(jī)制信號(hào)量集合 信

27、號(hào)量數(shù)組:在IPC信號(hào)量機(jī)制中把多個(gè)信號(hào)量組成一個(gè)信號(hào)量集合,該集合由信號(hào)量結(jié)構(gòu)體sem組成,稱為信號(hào)量數(shù)組。 信號(hào)量集合描述符系統(tǒng)中的每個(gè)信號(hào)量集合用一個(gè)描述符描述其特征和記載其管理信息 。Struct semid_dsStruct_ipc_perm sem_perm;/*對(duì)信號(hào)量集合的訪問(wèn)權(quán)限*/Time_t sem_otime;/*最后操作信號(hào)量集的時(shí)間*/Time_t sem_ctime;/*最后修改信號(hào)量集的時(shí)間*/Struct sem *sem_base;/*指向信號(hào)量數(shù)組*/Struct sem_queue *sem_pending;/*指向等待隊(duì)列頭*/Struct sem_q

28、ueue *sem_pending_last;/* 指向等待隊(duì)列尾*/Struct sem_undo *undo;/*/Unshort sem_nsems;/*信號(hào)量集合中信號(hào)量的數(shù)目*/IPC信號(hào)量機(jī)制IPC對(duì)系統(tǒng)中的所有信號(hào)量集合進(jìn)行集中管理,把所有的信號(hào)量集合描述符組織在一個(gè)semary數(shù)組中,其定義如下:Static struct semid_ds *smearySEMMNI;其中SEMMNI是系統(tǒng)中可以設(shè)置的信號(hào)量集合的最大數(shù)目 IPC信號(hào)量機(jī)制信號(hào)量集合的創(chuàng)建Int semget(key_t key, int nsems, int semflg)參數(shù)說(shuō)明:Key:要?jiǎng)?chuàng)建或要獲取的信

29、號(hào)量集合的標(biāo)志鍵值(與前同) 。Nsems:指出要?jiǎng)?chuàng)建的信號(hào)量集合中包含的信號(hào)量的個(gè)數(shù)。Semflgs:操作標(biāo)志;指定了信號(hào)量集合的訪問(wèn)權(quán)限和操作模式(與前同)。 返回值:該系統(tǒng)調(diào)用正常則返回值為信號(hào)量集合的標(biāo)識(shí)號(hào),出錯(cuò)則返回負(fù)數(shù)。IPC信號(hào)量機(jī)制信號(hào)量PV操作IPC中沒(méi)有對(duì)信號(hào)量分別設(shè)置P和V操作原語(yǔ),而是統(tǒng)一由具有原語(yǔ)性質(zhì)的系統(tǒng)調(diào)用semop()實(shí)現(xiàn)的,通常稱其為信號(hào)量操作函數(shù)。其定義如下:Int semop(int semid,struct sembuf *sops, unsigned nsops); 參數(shù)說(shuō)明:Semid:實(shí)施pv操作的信號(hào)量集合的標(biāo)識(shí)號(hào)Nsops:本次實(shí)施操作的信號(hào)量

30、的個(gè)數(shù)Sops:指向一個(gè)信號(hào)量操作數(shù)組。因?yàn)槊看螌?duì)信號(hào)量集合中實(shí)施操作的信號(hào)量個(gè)數(shù)不同,不同信號(hào)量實(shí)施的操作不同,所以必須指明本次操作是對(duì)哪些信號(hào)量,實(shí)施哪些操作。該數(shù)組的元素個(gè)數(shù)就是Nsops。IPC信號(hào)量機(jī)制Sops中的每個(gè)元素是一個(gè)sembuf結(jié)構(gòu)體:Struct sembufUshort sem_num; /*指出信號(hào)量在信號(hào)量數(shù)組中的下標(biāo)*/Short sem_op;/*指出操作的種類*/Short sem_flg;/*指出操作的標(biāo)志: 通常取值0;若為IPC_NOWAIT,則即使出現(xiàn)需要進(jìn)程阻塞的情況,也不阻塞,而是繼續(xù)運(yùn)行。*/Sem_op的值決定操作的類型:0:表示進(jìn)程釋放資源,則實(shí)施V操作,把semval的值加上sem_op以上兩種情況下:若對(duì)信號(hào)量集實(shí)施操作后,所有信號(hào)量的值semval均0,則函數(shù)返回0,表示進(jìn)程所需的多個(gè)資源都可用,此時(shí)進(jìn)程可以繼續(xù)運(yùn)行;否則,只要有一個(gè)semval0,則表示進(jìn)程需要的這種資源不可用,進(jìn)程阻塞。=0。此時(shí)若semval也是0,則函數(shù)返回,調(diào)用semop的進(jìn)程繼續(xù)執(zhí)行;若semval非0,則進(jìn)程被阻塞。IPC信號(hào)量機(jī)制信號(hào)量操作等待隊(duì)列 進(jìn)程執(zhí)行信號(hào)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論