進(jìn)程間通信-IPC_第1頁(yè)
進(jìn)程間通信-IPC_第2頁(yè)
進(jìn)程間通信-IPC_第3頁(yè)
進(jìn)程間通信-IPC_第4頁(yè)
進(jìn)程間通信-IPC_第5頁(yè)
已閱讀5頁(yè),還剩110頁(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)程間通信linux進(jìn)程間通信進(jìn)程間通信IPC(interprocess Communication)提供了一種不同進(jìn)程間可以互相訪問(wèn)數(shù)據(jù)的方式。相互訪問(wèn)的數(shù)據(jù)不僅包括程序運(yùn)行時(shí)的適時(shí)數(shù)據(jù),也包括對(duì)對(duì)方代碼段的訪問(wèn)。進(jìn)程間通信的目的: 1、數(shù)據(jù)傳輸:一個(gè)進(jìn)程需要將它的數(shù)據(jù)發(fā)送給另一個(gè)進(jìn)程,發(fā)送的數(shù)據(jù)量在一個(gè)字節(jié)到幾兆字節(jié)之間。2、共享數(shù)據(jù):多個(gè)進(jìn)程想要操作共享數(shù)據(jù),一個(gè)進(jìn)程對(duì)共享數(shù)據(jù)的修改,別的進(jìn)程應(yīng)該立刻看到。3、通知事件:一個(gè)進(jìn)程需要向另一個(gè)或一組進(jìn)程發(fā)送消息,通知它(它們)發(fā)生了某種事件(如進(jìn)程終止時(shí)要通知父進(jìn)程)。4、資源共享:多個(gè)進(jìn)程之間共享同樣的資源。為了作到這一點(diǎn),需要

2、內(nèi)核提供鎖和同步機(jī)制。5、進(jìn)程控制:有些進(jìn)程希望完全控制另一個(gè)進(jìn)程的執(zhí)行(如Debug進(jìn)程),此時(shí)控制進(jìn)程希望能夠攔截另一個(gè)進(jìn)程的所有異常,并能夠及時(shí)知道它的狀態(tài)改變。linux進(jìn)程間通信發(fā)展歷史linux進(jìn)程間通信(IPC)由以下幾部分發(fā)展而來(lái):linux進(jìn)程間通信方式目前Linux 中使用較多的進(jìn)程間通信方式:(1)管道(Pipe)及有名管道(named pipe) :管道可用于具有親緣關(guān)系進(jìn)程間的通信;有名管道,除具有管道所具有的功能外,它還允許無(wú)親緣關(guān)系進(jìn)程間的通信。(2)信號(hào)(Signal) :信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,它是比較復(fù)雜的通信方式,用于通知接受進(jìn)程有某事件發(fā)

3、生,一個(gè)進(jìn)程收到一個(gè)信號(hào)與處理器收到一個(gè)中斷請(qǐng)求效果上可以說(shuō)是一樣的。(3)消息(message)隊(duì)列:消息隊(duì)列是消息的鏈接表,包括 Posix 消息隊(duì)列 systemV 消息隊(duì)列。它克服了前兩種通信方式中信息量有限的缺點(diǎn),具有寫權(quán)限的進(jìn)程可以向消息隊(duì)列中按照一定的規(guī)則添加新消息;對(duì)消息隊(duì)列有讀權(quán)限的進(jìn)程則可以從消息隊(duì)列中讀取消息。linux進(jìn)程間通信(4)共享內(nèi)存(shared memory) :可以說(shuō)這是最有用的進(jìn)程間通信方式。它使得多個(gè)進(jìn)程可以訪問(wèn)同一塊內(nèi)存空間,不同進(jìn)程可以及時(shí)看到對(duì)方進(jìn)程中對(duì)共享內(nèi)存中數(shù)據(jù)的更新。這種通信方式需要依靠某種同步機(jī)制,如互斥鎖和信號(hào)量等。(5)信號(hào)量(se

4、maphore) :主要作為進(jìn)程間以及同一進(jìn)程不同線程之間的同步手段。(6)套接字(Socket) :這是一種更為一般的進(jìn)程間通信機(jī)制,它可用于不同機(jī)器之間的進(jìn)程間通信,應(yīng)用常廣泛。管道通信管道通信是linux 中比較常見(jiàn),也比較原始的通信方式之一,它實(shí)現(xiàn)了數(shù)據(jù)以一種數(shù)據(jù)流的方式,在多進(jìn)程間流動(dòng)。管道:是指用于連接一個(gè)讀進(jìn)程和一個(gè)寫進(jìn)程,以實(shí)現(xiàn)它們之間通信的共享文件,又稱pipe文件。 管道是單向的、先進(jìn)先出的、無(wú)結(jié)構(gòu)的、固定大小的字節(jié)流,它把一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出和另一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入連接在一起。 寫進(jìn)程在管道的尾端寫入數(shù)據(jù),讀進(jìn)程在管道的首端讀出數(shù)據(jù)。 數(shù)據(jù)讀出后將從管道中移走,其它讀進(jìn)程都不

5、能再讀到這些數(shù)據(jù)。 管道提供了簡(jiǎn)單的流控制機(jī)制。進(jìn)程試圖讀空管道時(shí),在有數(shù)據(jù)寫入管道前,進(jìn)程將一直阻塞。同樣,管道已經(jīng)滿時(shí),進(jìn)程再試圖寫管道,在其它進(jìn)程從管道中移走數(shù)據(jù)之前,寫進(jìn)程將一直阻塞。管道分類: 無(wú)名管道: (匿名管道)在系統(tǒng)中沒(méi)有實(shí)名,不能在文件系統(tǒng)中以任何方式看到該管道,它只是進(jìn)程的一種資源,會(huì)隨著進(jìn)程的結(jié)束而被系統(tǒng)清除。 有名管道:也稱為FIFO管道,是一種文件類型,在文件系統(tǒng)中可以查看到。7匿名管道(pipe) 對(duì)匿名管道兩端進(jìn)程而言,是一個(gè)只存在于內(nèi)存的特殊文件 匿名管道是半雙工的,數(shù)據(jù)只能向一個(gè)方向流動(dòng) 一個(gè)進(jìn)程將數(shù)據(jù)寫入管道,另一進(jìn)程從管道中讀取數(shù)據(jù) 寫入的內(nèi)容添加在管道

6、緩沖區(qū)的末尾,每次都是從緩沖區(qū)頭部讀出數(shù)據(jù) 雙向通信的建立 需要建立起兩個(gè)管道 使用限制 只能用于具有親緣關(guān)系的進(jìn)程之間 如父子進(jìn)程或兄弟進(jìn)程之間管道通信管道通信8匿名管道的建立 基本函數(shù) int pipe(int fd2); 參數(shù)說(shuō)明 fd2描述管道兩端 fd0只能用于讀,稱為管道讀端 fd1只能用于寫,稱為管道寫端 若試圖從寫端讀,或者向讀端寫都將導(dǎo)致錯(cuò)誤發(fā)生 返回值 成功時(shí)返回0,失敗時(shí)返回-1 說(shuō)明 基本文件I/O函數(shù)都可用于管道 如close()、read()、write()等 低層系統(tǒng)調(diào)用 sys_pipe( )-do_pipe()管道通信管道通信9匿名管道的讀操作 進(jìn)程調(diào)用rea

7、d()系統(tǒng)調(diào)用 內(nèi)核最終調(diào)用與該文件描述符相關(guān)的文件操作表中所找到的read()方法 在管道情形下,read方法將指向pipe_read()函數(shù) 該系統(tǒng)調(diào)用可能以兩種方式阻塞當(dāng)前進(jìn)程 系統(tǒng)調(diào)用開始時(shí)管道緩沖區(qū)為空 管道緩沖區(qū)沒(méi)有包含所請(qǐng)求的字節(jié)(n個(gè)字節(jié)),寫進(jìn)程在等待緩沖區(qū)的空間時(shí)曾經(jīng)被置為睡眠10匿名管道的寫操作 進(jìn)程調(diào)用write()系統(tǒng)調(diào)用 內(nèi)核最終調(diào)用pipe_write()函數(shù) 如果管道沒(méi)有讀進(jìn)程,寫進(jìn)程發(fā)送SIGPIPE信號(hào) 管道緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程將試圖寫入數(shù)據(jù) 如果讀進(jìn)程不讀出管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將一直阻塞匿名管道示例一#include#include#inc

8、ludeint main(void) int fd2; char str256; if( pipe(fd)0 ) perror(pipe); exit(1); write(fd1, Create the pipe successfully!n, 31); read(fd0, str, sizeof(str); printf(%sn,str); close(fd0); close(fd1); return 0; 單個(gè)進(jìn)程中的管道幾乎沒(méi)有任何用處。通常,調(diào)用 p i p e的進(jìn)程接著調(diào)用 f o r k,這樣就創(chuàng)建了從父進(jìn)程到子進(jìn)程或反之的 I P C通道。 f o r k之后做什么取決于我們想要

9、有的數(shù)據(jù)流的方向。對(duì)于從父進(jìn)程到子進(jìn)程的管道,父進(jìn)程關(guān)閉管道的讀端(f d 0 ) ,子進(jìn)程則關(guān)閉寫端(f d 1 ) 。對(duì)于從子進(jìn)程到父進(jìn)程的管道,父進(jìn)程關(guān)閉 f d 1 ,子進(jìn)程關(guān)閉f d 0 。12#include#include#include#define BUFSZ 256int main(void) int fd2; char bufBUFSZ; pid_t pid; int len; if( pipe(fd)0 ) perror(failed to pipe); exit(1); if( (pid = fork() 0) printf(This is farther, writ

10、e to fd1n,fd0,fd1); close(fd0); write(fd1, farther write,child readn, 25); exit(0); else printf(This is child ,read from fd0n); close(fd1); read(fd0, buf, BUFSZ); printf(%sn, buf); return 0;匿名管道-父子進(jìn)程間通信匿名管道操作基本流程 管道操作的基本流程:1)使用pipe函數(shù)創(chuàng)建管道;2)用fork函數(shù)創(chuàng)建一個(gè)子進(jìn)程;3)關(guān)閉父子進(jìn)程中不需要的文件描述符,使用管道進(jìn)行通信;由于以上對(duì)管道的操作是比較規(guī)范,也

11、比較常用。所以在ANSI C中將以上操作定義在兩個(gè)標(biāo)準(zhǔn)庫(kù)函數(shù)中,分別是popen和pclose函數(shù)。 FILE * popen(const char * command, const char * type) ; int pclose(FILE * f p) ; 參數(shù)command是一個(gè)在shell中可以運(yùn)行的命令字符串的指針; 參數(shù)type是一個(gè)字符指針,這個(gè)參數(shù)只有兩種值,分別是r和w,分別對(duì)應(yīng)popen函數(shù)的返回值是一個(gè)讀打開文件指針,還是寫打開文件指針。函數(shù)失敗返回NULL,并設(shè)置出錯(cuò)變量errno。pclose函數(shù)的參數(shù)fp是一個(gè)popen打開的文件描述符,函數(shù)失敗時(shí)返回-1。#in

12、clude #include #include #include #include #define BUFES PIPE_BUFint main(void) FILE *fp; char *cmd = ls -l; char bufBUFES; if(fp = popen(cmd, r) = NULL) perror(failed to openn); exit(1); while(fgets(buf, BUFES, fp) != NULL) printf(%sn, buf); pclose(fp); exit(0);Popen示例16有名管道 匿名管道缺點(diǎn) 沒(méi)有名字,只能用于具有親緣關(guān)系的進(jìn)

13、程間通信 FIFO(有名管道) 嚴(yán)格遵循先進(jìn)先出的讀寫規(guī)則 有名字,F(xiàn)IFO的名字包含在系統(tǒng)的目錄樹結(jié)構(gòu)中,支持無(wú)親緣關(guān)系的進(jìn)程按名字訪問(wèn) 類似管道,在文件系統(tǒng)中不存在數(shù)據(jù)塊,而是與一塊內(nèi)核緩沖區(qū)相關(guān)聯(lián) read和write操作也由pipe_read()和pipe_write() 實(shí)現(xiàn) 與匿名管道主要區(qū)別 FIFO索引節(jié)點(diǎn)出現(xiàn)在系統(tǒng)目錄樹上而不是pipefs特殊文件系統(tǒng)中 FIFO是一種雙向通信管道,可以以讀/寫模式打開一個(gè)FIFO17有名管道的建立 基本函數(shù) int mkfifo(const char * pathname, mode_t mode); 參數(shù)說(shuō)明 pathname:創(chuàng)建的FI

14、FO名字 mode:規(guī)定FIFO的讀寫權(quán)限 返回值 成功時(shí)返回0 失敗時(shí)返回-1 若路徑名存在,則返回EEXIST錯(cuò)誤 說(shuō)明 一般文件的I/O函數(shù)都可用于管道,如open(), close(), read(), write()等。18有名管道的open() 打開規(guī)則 為讀操作而打開FIFO文件 若已有進(jìn)程為寫而打開該FIFO,則當(dāng)前打開操作將成功返回 否則,可能阻塞直到有相應(yīng)進(jìn)程為寫而打開該FIFO(當(dāng)前打開操作設(shè)置未設(shè)置O_NONBLOCK標(biāo)志) 或立即返回(當(dāng)前打開操作設(shè)置O_NONBLOCK標(biāo)志) 為寫操作而打開FIFO文件 如果已經(jīng)有進(jìn)程為讀而打開該FIFO,則當(dāng)前打開操作將成功返回

15、否則,可能阻塞直到有相應(yīng)進(jìn)程為讀而打開該FIFO(當(dāng)前打開操作未設(shè)置O_NONBLOCK標(biāo)志) 或者,返回ENXIO錯(cuò)誤(當(dāng)前打開操作設(shè)置O_NONBLOCK標(biāo)志) 實(shí)例:1,mkfifo testfifo 建立有名管道文件testfifo;2,ls testfifo 向有名管道文件寫入”ls”命令顯示的內(nèi)容;3,cat testfifo 用”cat”命令讀取”testfifo”文件中的內(nèi)容;19有名管道示例創(chuàng)建有名管道#include#include#include#include#include#include#include#includeint main(int argc, char*

16、 argv)/mode_t mode = 0666;mode_t mode = O_NONBLOCK;if( argc!=2 ) printf(USEMSG: create_fifo fifonamen); exit(1);if(mkfifo(argv1,mode)0) perror(failed to mkfifo); exit(1);elseprintf(you successfully create a FIFO name is:%sn,argv1);exit(0); 20有名管道舉例讀有名管道 #include #include #include #include #include #

17、include #include #include #define BUFES PIPE_BUF int main(void) int fd; int len; char bufBUFES; if(fd=open(testfifo,O_RDONLY)0) printf(read: %s,buf); close(fd); return 0; 21有名管道示例寫有名管道#include#include#include#include#include#include#include#include#define BUFES PIPE_BUFint main(void) int fd; int n,

18、i; if( (fd=open(testfifo,O_WRONLY) 0) perror(open); exit(1); for(i=0; i10; i+) if ( write(fd,message n,9)0 ) perror(write); exit(1); close(fd); return 0;22信號(hào)的本質(zhì) 信號(hào)是一種進(jìn)程間異步通信機(jī)制,可以看作是異步通知,通知接收信號(hào)的進(jìn)程有哪些事情發(fā)生了。在實(shí)現(xiàn)上是一種軟中斷。是對(duì)中斷的模擬,也稱軟中斷信號(hào)或軟中斷。 信號(hào)可以導(dǎo)致一個(gè)正在運(yùn)行的進(jìn)程被異步打斷,讓進(jìn)程知道已經(jīng)發(fā)生了一個(gè)特定事件; 強(qiáng)迫進(jìn)程執(zhí)行自身代碼中的信號(hào)處理程序; 發(fā)給非運(yùn)行

19、進(jìn)程的信號(hào)必須由內(nèi)核保存,直到進(jìn)程恢復(fù)執(zhí)行; 阻塞一個(gè)信號(hào)要求信號(hào)的傳遞被延遲,直到隨后解除阻塞; 每個(gè)信號(hào)都有名字,這些名字都是以SIG開頭; 不存在編號(hào)為0的信號(hào)。信號(hào)來(lái)源硬件來(lái)源硬件操作,如按Ctrl+C硬件故障軟件來(lái)源常用信號(hào)發(fā)送函數(shù),如kill(), raise(), alarm()非法運(yùn)算(浮點(diǎn)運(yùn)算溢出或內(nèi)存訪問(wèn)錯(cuò)誤等也可產(chǎn)生信號(hào)24信號(hào)分類 不可靠信號(hào) 信號(hào)值小于SIGRTMIN; 進(jìn)程每次處理信號(hào)后,將信號(hào)響應(yīng)函數(shù)設(shè)置為默認(rèn)動(dòng)作,需調(diào)用signal() 重新安裝信號(hào) ; 非實(shí)時(shí)信號(hào)都是不可靠信號(hào),不支持排隊(duì),信號(hào)可能丟失; 可靠信號(hào) 信號(hào)值介于SIGRTMIN和SIGRTMAX

20、之間; 新信號(hào)安裝函數(shù)sigaction()和信號(hào)發(fā)送函數(shù)sigqueue(); 實(shí)時(shí)信號(hào)都是可靠信號(hào),支持排隊(duì);信號(hào)通信信號(hào)通信25進(jìn)程對(duì)信號(hào)的響應(yīng)方式 忽略信號(hào) 進(jìn)程忽略接收到的信號(hào),不做任何處理; SIGKILL和SIGSTOP不能忽略; 不能為SIGKILL和SIGSTOP設(shè)置新的信號(hào)處理函數(shù)。 捕獲信號(hào) 類似中斷處理程序,一旦捕獲到相應(yīng)信號(hào),執(zhí)行對(duì)應(yīng)的信號(hào)處理函數(shù); 進(jìn)程可通過(guò)signal()/sigaction()指定進(jìn)程對(duì)某個(gè)信號(hào)的處理行為; 缺省操作 Linux內(nèi)核為信號(hào)提供默認(rèn)處理程序處理;26常見(jiàn)信號(hào)1SIGHUP從終端上發(fā)出的結(jié)束信號(hào)從終端上發(fā)出的結(jié)束信號(hào)2SIGINT來(lái)

21、自鍵盤的中斷信號(hào)(來(lái)自鍵盤的中斷信號(hào)(Ctrl-c)3SIGQUIT來(lái)自鍵盤的退出信號(hào)(來(lái)自鍵盤的退出信號(hào)(Ctrl-)8SIGSTOP進(jìn)程收到該信號(hào)后會(huì)暫停執(zhí)行,進(jìn)入暫停態(tài)進(jìn)程收到該信號(hào)后會(huì)暫停執(zhí)行,進(jìn)入暫停態(tài)9SIGKILL立即結(jié)束程序,立即結(jié)束程序,不能被阻塞不能被阻塞,處理和忽略,處理和忽略14 SIGALRM 進(jìn)程的定時(shí)器到期時(shí),發(fā)送該信號(hào)進(jìn)程的定時(shí)器到期時(shí),發(fā)送該信號(hào)18 SIGCONT處于阻塞狀態(tài)的進(jìn)程收到該信號(hào)后會(huì)繼續(xù)執(zhí)處于阻塞狀態(tài)的進(jìn)程收到該信號(hào)后會(huì)繼續(xù)執(zhí)行行17 SIGCHLD子進(jìn)程退出時(shí)給父進(jìn)程發(fā)送該信號(hào)子進(jìn)程退出時(shí)給父進(jìn)程發(fā)送該信號(hào)27信號(hào)生命周期信號(hào)誕生 觸發(fā)信號(hào)的事

22、件發(fā)生(如檢測(cè)到硬件異常、定時(shí)器超時(shí)以及調(diào)用信號(hào)發(fā)送函數(shù)kill()或sigqueue()等)。信號(hào)在進(jìn)程中注冊(cè) 內(nèi)核更新目標(biāo)進(jìn)程的數(shù)據(jù)結(jié)構(gòu),將信號(hào)加入進(jìn)程的未決信號(hào)集,并將信號(hào)所攜信息保存到某個(gè)sigqueue結(jié)構(gòu)中 對(duì)實(shí)時(shí)信號(hào),不管其是否已在進(jìn)程中注冊(cè),都被再次注冊(cè) 對(duì)非實(shí)時(shí)信號(hào),若該信號(hào)已在進(jìn)程中注冊(cè),則將其丟棄信號(hào)在進(jìn)程中注銷 進(jìn)程從核心空間返回用戶空間時(shí)都檢測(cè)是否有信號(hào)等待處理 若存在等待處理且未被阻塞的未決信號(hào),則將其在未決信號(hào)鏈中占有的結(jié)構(gòu)卸掉(對(duì)實(shí)時(shí)進(jìn)程只刪除sigqueue結(jié)構(gòu))信號(hào)處理函數(shù)執(zhí)行完畢 執(zhí)行相應(yīng)信號(hào)處理函數(shù)或改變目標(biāo)進(jìn)程的執(zhí)行狀態(tài)28信號(hào)在進(jìn)程中注冊(cè) 進(jìn)程的ta

23、sk_struct結(jié)構(gòu)中有關(guān)于本進(jìn)程中未決信號(hào)的數(shù)據(jù)成員: struct sigpending中第三個(gè)成員signal是進(jìn)程中所有未決信號(hào)集,第一、第二個(gè)成員分別指向一個(gè)sigqueue類型的鏈表的(稱之為“未決信號(hào)信息鏈”)的首尾,該鏈中的每個(gè)sigqueue結(jié)構(gòu)包含一個(gè)特定信號(hào)所攜帶的信息,并指向下一個(gè)sigqueue結(jié)構(gòu):struct sigpending pending;struct sigpendingstruct sigqueue *head, *tail;sigset_t signal;struct sigqueuestruct sigqueue *next;siginfo_t

24、info;信號(hào)在進(jìn)程中注銷 在目標(biāo)進(jìn)程執(zhí)行過(guò)程中,會(huì)檢測(cè)是否有信號(hào)等待處理(每次從系統(tǒng)空間返回到用戶空間時(shí)都做這樣的檢查)。如果存在未決信號(hào)等待處理且該信號(hào)沒(méi)有被進(jìn)程阻塞,則在運(yùn)行相應(yīng)的信號(hào)處理函數(shù)前,進(jìn)程會(huì)把信號(hào)在未決信號(hào)鏈中占有的結(jié)構(gòu)卸掉。是否將信號(hào)從進(jìn)程未決信號(hào)集中刪除對(duì)于實(shí)時(shí)與非實(shí)時(shí)信號(hào)是不同的。對(duì)于非實(shí)時(shí)信號(hào)來(lái)說(shuō),由于在未決信號(hào)信息鏈中最多只占用一個(gè)sigqueue結(jié)構(gòu),因此該結(jié)構(gòu)被釋放后,應(yīng)該把信號(hào)在進(jìn)程未決信號(hào)集中刪除(信號(hào)注銷完畢);而對(duì)于實(shí)時(shí)信號(hào)來(lái)說(shuō),可能在未決信號(hào)信息鏈中占用多個(gè)sigqueue結(jié)構(gòu),因此應(yīng)該針對(duì)占用sigqueue結(jié)構(gòu)的數(shù)目區(qū)別對(duì)待:如果只占用一個(gè)sigq

25、ueue結(jié)構(gòu)(進(jìn)程只收到該信號(hào)一次),則應(yīng)該把信號(hào)在進(jìn)程的未決信號(hào)集中刪除(信號(hào)注銷完畢)。否則,不應(yīng)該在進(jìn)程的未決信號(hào)集中刪除該信號(hào)(信號(hào)注銷完畢)。 進(jìn)程在執(zhí)行信號(hào)相應(yīng)處理函數(shù)之前,首先要把信號(hào)在進(jìn)程中注銷。30信號(hào)處理函數(shù) 信號(hào)發(fā)送函數(shù) kill(), sigqueue(), raise(), alarm(), setitimer(), pause(),abort() 信號(hào)安裝函數(shù) signal(), sigaction() 信號(hào)集操作函數(shù) sigemptyset(), sigfillset(), sigaddset(), sigdelset(), sigismember()31信號(hào)發(fā)送

26、函數(shù)kill()#include #include int kill(pid_t pid,int signo) 功能 向進(jìn)程或進(jìn)程組發(fā)送一個(gè)信號(hào) (成功返回 0; 否則,返回 -1 )參數(shù)說(shuō)明 pid:接收信號(hào)的進(jìn)程(組)的進(jìn)程號(hào) pid0:發(fā)送給進(jìn)程號(hào)為pid的進(jìn)程 pid=0:發(fā)送給當(dāng)前進(jìn)程所屬進(jìn)程組里的所有進(jìn)程 pid=-1:發(fā)送給除1號(hào)進(jìn)程和自身以外的所有進(jìn)程 pid-1:發(fā)送給屬于進(jìn)程組-pid的所有進(jìn)程 signo:發(fā)送的信號(hào) Signo = 0:不發(fā)送信號(hào),可用于檢查目標(biāo)進(jìn)程是否存在,以及當(dāng)前進(jìn)程是否具有向目標(biāo)進(jìn)程發(fā)送信號(hào)的權(quán)限(root權(quán)限的進(jìn)程可以向任何進(jìn)程發(fā)送信號(hào),非roo

27、t權(quán)限的進(jìn)程只能向?qū)儆谕粋€(gè)session或者同一個(gè)用戶的進(jìn)程發(fā)送信號(hào))。#include #include #include #include #include int main( void ) pid_t childpid; int status; int retval; childpid = fork(); if ( -1 = childpid ) perror( fork() ); exit( EXIT_FAILURE ); else if ( 0 = childpid ) puts( In child process ); sleep( 100 );/讓子進(jìn)程睡眠,看看父進(jìn)程的行為

28、exit(EXIT_SUCCESS); else if ( 0 = (waitpid( childpid, &status, WNOHANG ) retval = kill( childpid,SIGKILL ); if ( retval ) puts( kill failed. ); perror( kill ); waitpid( childpid, &status, 0 ); else printf( %d killedn, childpid ); exit(EXIT_SUCCESS); 33信號(hào)發(fā)送函數(shù)sigqueue()#include #include int si

29、gqueue(pid_t pid, int signo, const union sigval sigval_t) 調(diào)用成功返回 0;否則,返回 -1。功能 主要針對(duì)實(shí)時(shí)信號(hào),支持帶有參數(shù)信號(hào),與函數(shù)sigaction()配合使用參數(shù)說(shuō)明 pid:接收信號(hào)的進(jìn)程ID signo:待發(fā)送信號(hào) sigval_t:信號(hào)傳遞的參數(shù)(4字節(jié))說(shuō)明 調(diào)用sigqueue()時(shí),sigval_t被拷貝到信號(hào)處理函數(shù) sigqueue()發(fā)送非實(shí)時(shí)信號(hào)時(shí) sigval_t包含的信息仍然能夠傳遞給信號(hào)處理函數(shù) 仍然不支持排隊(duì),所有相同信號(hào)都被合并為一個(gè)信號(hào)34sigqueue()向信號(hào)傳遞附加消息的流程 sig

30、queue()的第三個(gè)參數(shù)是sigval聯(lián)合數(shù)據(jù)結(jié)構(gòu) 調(diào)用sigqueue()時(shí),該數(shù)據(jù)結(jié)構(gòu)中的數(shù)據(jù)將被拷貝到信號(hào)處理函數(shù)sigaction()的第二個(gè)參數(shù) 這樣,就可在發(fā)送信號(hào)的同時(shí)讓信號(hào)傳遞一些附加信息 typedef union sigval int sival_int; void *sival_ptr; sigval_t;35Kill()與sigqueue()區(qū)別 sigqueue()比kill()傳遞更多的附加信息 sigqueue()只能向一個(gè)進(jìn)程發(fā)送信號(hào)信號(hào)通信信號(hào)通信36信號(hào)發(fā)送函數(shù)raise()#include int raise(int signo) 功能 向自身發(fā)送信號(hào)

31、參數(shù)說(shuō)明 signo:發(fā)送的信號(hào) signo=0:不發(fā)送信號(hào)返回值 成功時(shí),返回0 錯(cuò)誤時(shí),返回-1說(shuō)明 raise()可以通過(guò)kill( )實(shí)現(xiàn),raise(signo)等價(jià)于 kill(getpid( ), signo);信號(hào)通信信號(hào)通信 #include #include int main(void) printf(kill myself!n); raise(SIGKILL); printf(can you see this?n); return 0; 38信號(hào)發(fā)送函數(shù)alarm()#include unsigned int alarm(unsigned int seconds) 功能

32、設(shè)置定時(shí)器,當(dāng)計(jì)時(shí)時(shí)間到達(dá)時(shí),向進(jìn)程發(fā)出SIGALRM信號(hào)參數(shù)說(shuō)明 seconds:等待秒數(shù) seconds為0時(shí),取消先前設(shè)置的鬧鐘,返回鬧鐘剩余時(shí)間u若之前未設(shè)鬧鐘,則返回0說(shuō)明 alarm()只發(fā)送一次信號(hào) 若需重復(fù)設(shè)定定時(shí)器,則要多次調(diào)用alarm()函數(shù) 信號(hào)通信信號(hào)通信#include #include #include #include #include void handler() printf(hellonn);main()int i;signal(SIGALRM,handler);alarm(5);for(i=1;i7;i+)printf(sleep %d n,i);sle

33、ep(1);40信號(hào)發(fā)送函數(shù)setitimer()函數(shù)原型 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 參數(shù)說(shuō)明 which:邏輯定時(shí)器類型 ITIMER_REAL:按實(shí)際時(shí)間計(jì)時(shí),計(jì)時(shí)到達(dá)時(shí)向進(jìn)程發(fā)送SIGALRM信號(hào)。 ITIMER_VIRTUAL:計(jì)算進(jìn)程在用戶態(tài)執(zhí)行的時(shí)間,計(jì)時(shí)到達(dá)將發(fā)送SIGVTALRM信號(hào)給進(jìn)程。 ITIMER_PROF:計(jì)算進(jìn)程在用戶態(tài)和核心態(tài)的總時(shí)間。計(jì)時(shí)到達(dá)將發(fā)送SIGPROF信號(hào)給進(jìn)程。u與ITIMER_VIRTUAL是一對(duì),該定時(shí)器經(jīng)常

34、用來(lái)統(tǒng)計(jì)進(jìn)程在用戶態(tài)和核心態(tài)花費(fèi)的時(shí)間 value:指明定時(shí)器的時(shí)間 ovalue:如果不為空,則保存上次調(diào)用設(shè)定的值功能 指定一段時(shí)間后,執(zhí)行某個(gè)function; 每間格一段時(shí)間就執(zhí)行某個(gè)function41信號(hào)發(fā)送函數(shù)setitimer() (續(xù))返回值 成功時(shí),返回0 錯(cuò)誤時(shí),返回-1struct itimerval結(jié)構(gòu)定義struct itimerval struct timeval it_interval; /*定時(shí)器周期*/ struct timeval it_value; /*定時(shí)器剩的時(shí)間,為0時(shí)發(fā)信號(hào)*/; struct timeval結(jié)構(gòu)定義struct timeval

35、long tv_sec; /*秒*/ long tv_usec; /*微秒,1秒=1000000微秒*/; it_value為為0是不會(huì)觸發(fā)信號(hào)的,所以要能觸發(fā)信號(hào),是不會(huì)觸發(fā)信號(hào)的,所以要能觸發(fā)信號(hào),it_value得大于得大于0;如果如果it_interval為零,只會(huì)延時(shí),不會(huì)定時(shí)(也就是說(shuō)只會(huì)觸發(fā)一次為零,只會(huì)延時(shí),不會(huì)定時(shí)(也就是說(shuō)只會(huì)觸發(fā)一次信號(hào)信號(hào))。信號(hào)通信信號(hào)通信42信號(hào)發(fā)送函數(shù)setitimer()示例 #include #include #include void signalHandler(int signo) switch (signo) case SIGALRM:

36、printf(Caught the SIGALRM signal!n); break; int main(int argc, char *argv) signal(SIGALRM, signalHandler); struct itimerval new_value, old_value; new_value.it_value.tv_sec = 1; new_value.it_value.tv_usec = 0; new_value.it_interval.tv_sec = 2; new_value.it_interval.tv_usec = 0; setitimer(ITIMER_REAL,

37、 &new_value, &old_value); for(;); return 0; 43信號(hào)發(fā)送函數(shù)pause() 功能 使當(dāng)前進(jìn)程暫停,進(jìn)入睡眠狀態(tài),直到被信號(hào)所中斷,即將進(jìn)程掛起等待信號(hào)到來(lái)。 函數(shù)原型 int pause(void); 返回值 -1 舉例 使用alarm( )和pause( )實(shí)現(xiàn)sleep( )功能44信號(hào)發(fā)送函數(shù)pause()示例信號(hào)的安裝(設(shè)置信號(hào)關(guān)聯(lián)動(dòng)作)信號(hào)的安裝(設(shè)置信號(hào)關(guān)聯(lián)動(dòng)作) 如果進(jìn)程要處理某一信號(hào),那么就要在進(jìn)程中安裝該信號(hào)。安裝信號(hào)主要用來(lái)確定信號(hào)值及進(jìn)程針對(duì)該信號(hào)值的動(dòng)作之間的映射關(guān)系,即進(jìn)程將要處理哪個(gè)信處理哪個(gè)信號(hào)號(hào);該信號(hào)

38、被傳遞給進(jìn)程時(shí),將執(zhí)行何種操作執(zhí)行何種操作。 linux主要有兩個(gè)函數(shù)實(shí)現(xiàn)信號(hào)的安裝:signal()、sigaction()。其中signal()在非可靠信號(hào)系統(tǒng)調(diào)用的基礎(chǔ)上實(shí)現(xiàn), 是庫(kù)函數(shù)。它只有兩個(gè)參數(shù)兩個(gè)參數(shù),不支持信號(hào)傳遞信息,主要是用于前32種非實(shí)時(shí)信號(hào)的安裝;而sigaction()是較新的函數(shù)(由兩個(gè)系統(tǒng)調(diào)用實(shí)現(xiàn):sys_signal以及sys_rt_sigaction),有三個(gè)參數(shù)有三個(gè)參數(shù),支持信號(hào)傳遞信息,主要用來(lái)與 sigqueue() 系統(tǒng)調(diào)用配合使用,當(dāng)然,sigaction()同樣支持非實(shí)時(shí)信號(hào)的安裝。sigaction()優(yōu)于signal()主要體現(xiàn)在支持信號(hào)帶

39、有參數(shù)。46信號(hào)安裝函數(shù)signal() 原型定義 void (*signal(int signum, void (*handler)(int)(int); 參數(shù)說(shuō)明 signum:需要安裝的信號(hào) handler:與安裝信號(hào)相關(guān)的處理函數(shù),可以是SIG_IGN或SIG_DFL SIG_IGN:忽略該信號(hào) SIG_DFL:執(zhí)行默認(rèn)操作函數(shù) 返回值 成功時(shí),返回新安裝信號(hào)處理函數(shù)handler的值 失敗時(shí),返回SIG_ERR 底層系統(tǒng)調(diào)用 sys_signal(int sig, _sighandler_t handler)47信號(hào)安裝函數(shù)signal()示例#include #include #i

40、nclude #include void sig_usr(int sig);int main(int argc, char* argv) int i=0; if(signal(SIGUSR1, sig_usr) = SIG_ERR)printf(Cant catch SIGUSR1n); if(signal(SIGUSR2, sig_usr) = SIG_ERR) printf(“Cant catch SIGUSR2n”); while(1) printf(%2dn, i); pause(); i+; return 0;void sig_usr(int sig) if(sig = SIGUSR

41、1) printf(Received SIGUSR1n); else if(sig = SIGUSR2) printf(Received SIGUSR2n); else printf(Undeclared signal %d n,sig);執(zhí)行: Gcc signal.c o signal ./signal&(以后臺(tái)程序運(yùn)行,并顯示pid) Kill SIGUSR1 pid49信號(hào)安裝函數(shù)sigaction()原型定義int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); sig

42、action函數(shù)用于設(shè)定進(jìn)程接收到特定信號(hào)后的行為。第一個(gè)參數(shù)為信號(hào)的值,可以為除SIGKILL及SIGSTOP外的任何一個(gè)特定有效的信號(hào)(為這兩個(gè)信號(hào)定義自己的處理函數(shù),將導(dǎo)致信號(hào)安裝錯(cuò)誤)。第二個(gè)參數(shù)是指向結(jié)構(gòu)sigaction的一個(gè)實(shí)例的指針,在結(jié)構(gòu)sigaction的實(shí)例中,指定了對(duì)特定信號(hào)的處理,如果為空,進(jìn)程會(huì)以缺省方式對(duì)信號(hào)處理;第三個(gè)參數(shù)oldact指向的對(duì)象用來(lái)保存原來(lái)對(duì)相應(yīng)信號(hào)的處理,可指定oldact為NULL。如果把第二、第三個(gè)參數(shù)都設(shè)為NULL,那么該函數(shù)可用于檢查信號(hào)的有效性。第二個(gè)參數(shù)最為重要,其中包含了對(duì)指定信號(hào)的處理、信號(hào)所傳遞的信息、信號(hào)處理函數(shù)執(zhí)行過(guò)程中應(yīng)

43、屏蔽掉哪些函數(shù)等等。底層系統(tǒng)調(diào)用sys_sigaction(int sig, const struct old_sigaction _user *act, struct old_sigaction _user *oact) sigaction結(jié)構(gòu)定義如下: sa_restorer,已過(guò)時(shí),POSIX不支持它,不應(yīng)再被使用。 聯(lián)合數(shù)據(jù)結(jié)構(gòu)中的兩個(gè)元素_sa_handler以及*_sa_sigaction指定信號(hào)關(guān)聯(lián)函數(shù),即用戶指定的信號(hào)處理函數(shù)。除了可以是用戶自定義的處理函數(shù)外,還可以為SIG_DFL(采用缺省的處理方式),也可以為SIG_IGN(忽略信號(hào))。 struct sigaction

44、union _sighandler_t _sa_handler; void (*_sa_sigaction)( int, struct siginfo *, void *); _u sigset_t sa_mask; unsigned long sa_flags; void (*sa_restorer)(void); 由_sa_handler 指定的處理函數(shù)只有一個(gè)參數(shù),即信號(hào)值,所以信號(hào)不能傳遞除信號(hào)值之外的任何信息; 由_sa_sigaction 指定的信號(hào)處理函數(shù)帶有三個(gè)參數(shù),是為實(shí)時(shí)信號(hào)而設(shè)的(當(dāng)然同樣支持非實(shí)時(shí)信號(hào)),它指定一個(gè)3參數(shù)信號(hào)處理函數(shù)。第一個(gè)參數(shù)為信號(hào)值,第三個(gè)參數(shù)沒(méi)有使

45、用(posix沒(méi)有規(guī)范使用該參數(shù)的標(biāo)準(zhǔn)),第二個(gè)參數(shù)是指向siginfo_t 結(jié)構(gòu)的指針,結(jié)構(gòu)中包含信號(hào)攜帶的數(shù)據(jù)值,參數(shù)所指向的結(jié)構(gòu)如下:siginfo_t int si_signo; /* 信號(hào)值,對(duì)所有信號(hào)有意義*/ int si_errno; /* errno值,對(duì)所有信號(hào)有意義*/ int si_code; /* 信號(hào)產(chǎn)生的原因,對(duì)所有信號(hào)有意義*/ pid_t si_pid; /* 發(fā)送信號(hào)的進(jìn)程ID,對(duì)實(shí)時(shí)信號(hào)以及SIGCHLD有 意義 */ uid_t si_uid; /* 發(fā)送信號(hào)進(jìn)程的真實(shí)用戶ID,對(duì)kill(2),實(shí)時(shí)信號(hào)以及SIGCHLD有意義 */ int si_st

46、atus; /* 退出狀態(tài),對(duì)SIGCHLD有意義*/ clock_t si_utime; /* 用戶消耗的時(shí)間,對(duì)SIGCHLD有意義 */ clock_t si_stime; /* 內(nèi)核消耗的時(shí)間,對(duì)SIGCHLD有意義 */ sigval_t si_value; /* 信號(hào)值,對(duì)所有實(shí)時(shí)有意義,是一個(gè)聯(lián)合數(shù)據(jù)結(jié)構(gòu), /*可以為一個(gè)整數(shù)(由si_int標(biāo)示,也可以為一個(gè)指針,由si_ptr標(biāo)示)*/ void * si_addr; /* 觸發(fā)fault的內(nèi)存地址,對(duì)SIGILL,SIGFPE,SIGSEGV,SIGBUS 信號(hào)有意義*/ int si_band; /* 對(duì)SIGPOLL信號(hào)

47、有意義 */ int si_fd; /* 對(duì)SIGPOLL信號(hào)有意義 */ sa_mask:信號(hào)的集合。指定在信號(hào)處理程序執(zhí)行過(guò)程中,哪些信號(hào)應(yīng)當(dāng)被阻塞。缺省情況下當(dāng)前信號(hào)本身被阻塞,防止信號(hào)的嵌套發(fā)送。 注:sigaction()安裝信號(hào)的處理函數(shù)執(zhí)行過(guò)程中由sa_mask指定的信號(hào)才被阻塞。 sa_flags用于更改指定信號(hào)的行為。比較重要的標(biāo)志位是SA_SIGINFO,當(dāng)設(shè)定了該標(biāo)志位時(shí),表示信號(hào)附帶的參數(shù)可以被傳遞到信號(hào)處理函數(shù)中,因此,應(yīng)該為sigaction結(jié)構(gòu)中的sa_sigaction指定處理函數(shù),而不應(yīng)該為sa_handler指定信號(hào)處理函數(shù),否則,設(shè)置該標(biāo)志變得毫無(wú)意義。即

48、使為sa_sigaction指定了信號(hào)處理函數(shù),如果不設(shè)置SA_SIGINFO,信號(hào)處理函數(shù)同樣不能得到信號(hào)傳遞過(guò)來(lái)的數(shù)據(jù),在信號(hào)處理函數(shù)中對(duì)這些信息的訪問(wèn)都將導(dǎo)致段錯(cuò)誤(Segmentation fault)。54信號(hào)安裝函數(shù)sigaction()示例一#include #include #include #include void myFun(int sig);int main(int argc, char* argv) struct sigaction act, oldact; act.sa_handler = myFun; sigemptyset(&act.sa_mask);

49、act.sa_flags = 0; sigaction(SIGUSR1, &act, &oldact); while(1) printf(Hello world!n); pause(); void myFun(int sig) printf(I got a signal:%dn,sig); Gcc sigacton1.c o sigaction ./sigaction& Kill SIGUSR1 pid信號(hào)安裝函sigaction()數(shù)示例二#include #include #include #include void func(int signo, siginfo_

50、t *info, void *p) printf(signo = %dn, signo); printf(sender pid = %dn, info-si_pid);int main() struct sigaction act, oldact; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; act.sa_sigaction = func; sigaction(SIGUSR1, &act, &oldact); while(1) printf(pid is %d hello!n,getpid(); pause

51、(); 在另外一個(gè)終端發(fā)送信號(hào)給當(dāng)前進(jìn)程sigqueue()函數(shù)調(diào)用示例在不同進(jìn)程間傳遞整型參數(shù).信號(hào)接收程序 #include #include #include #include #include void myFun(int, siginfo_t*, void* myfun); int main(int argc, char* argv) struct sigaction act; int sig; pid_t pid; pid = getpid(); printf(pid is%dn,pid); sigemptyset(&act.sa_mask); act.sa_sigacti

52、on = myFun; act.sa_flags = SA_SIGINFO;56 if(sigaction(SIGUSR1, &act, NULL)si_int); printf(Recv signum is%dn,signo); /raise(SIGKILL); sigqueue()函數(shù)調(diào)用示例在不同進(jìn)程間傳遞整型參數(shù).信號(hào)發(fā)送程序#include #include #include #include #include #include main(int argc, char* argv) pid_t pid; int signum; union sigval mysigval; p

53、id = (pid_t)atoi(argv1); mysigval.sival_int = 8; if(sigqueue(pid, SIGUSR1, mysigval)=-1) printf(send errorn); sleep(2); return 0;57signal()與sigaction()的區(qū)別 不同點(diǎn) signal() 安裝的信號(hào)不能向信號(hào)處理函數(shù)傳遞信息 sigaction() 可設(shè)置進(jìn)程的信號(hào)掩碼,返回設(shè)置之前的sigaction結(jié)構(gòu) 安裝的信號(hào)可以向信號(hào)處理函數(shù)傳遞信息 相同點(diǎn) 都可以為指定的信號(hào)設(shè)置信號(hào)處理函數(shù) 共用同一個(gè)內(nèi)核函數(shù)do_sigaction()5859信號(hào)集

54、操作函數(shù)信號(hào)集定義函數(shù)原型 int sigemptyset(sigset_t *set); 初始化信號(hào)集合set,將set設(shè)置為空 int sigfillset(sigset_t *set); 初始化信號(hào)集合,將信號(hào)集set設(shè)置為包含所有信號(hào)的集合 int sigaddset(sigset_t *set, int signo); 將信號(hào)signo加入到信號(hào)集set中 int sigdelset(sigset_t *set, int signo); 將信號(hào)signo從信號(hào)集set中刪除 int sigismember(sigset_t *set, int signo); 查詢信號(hào)signo是否在

55、信號(hào)集set中 60信號(hào)操作函數(shù)sigprocmask( )功能 通過(guò)信號(hào)集set修改進(jìn)程的信號(hào)阻塞集函數(shù)原型 int sigprocmask(int how, const sigset_t *set, sigset_t *oset);參數(shù) how:函數(shù)操作方式 SIG_BLOCK:增加一個(gè)信號(hào)集到當(dāng)前進(jìn)程的阻塞集中 SIG_UNBLOCK:從當(dāng)前阻塞集中刪除一個(gè)信號(hào)集 SIG_SETMASK:將當(dāng)前信號(hào)集設(shè)置為信號(hào)阻塞集合 set:當(dāng)前進(jìn)程的信號(hào)集 oset:保存當(dāng)前進(jìn)程的信號(hào)阻塞集說(shuō)明 在使用之前需先設(shè)置好信號(hào)集合set61其他信號(hào)處理函數(shù) sigpending(sigset_t *set

56、) 獲取當(dāng)前進(jìn)程的未決信號(hào)集 set保存返回結(jié)果 sigsuspend(const sigset_t *mask) 在接收到某個(gè)信號(hào)之前,臨時(shí)用mask替換進(jìn)程的信號(hào)掩碼,并暫停進(jìn)程執(zhí)行,直到收到信號(hào)為止 sigsuspend返回后將恢復(fù)調(diào)用之前的信號(hào)掩碼 信號(hào)處理函數(shù)完成后,進(jìn)程將繼續(xù)執(zhí)行 該系統(tǒng)調(diào)用始終返回-1,并將errno設(shè)置為EINTRtask_struct中與信號(hào)處理相關(guān)的成員 struct signal_struct *signal 信號(hào)描述符結(jié)構(gòu),為每種信號(hào)選擇處理函數(shù) struct sighand_struct *sighand 包含信號(hào)處理函數(shù)描述符的數(shù)組,信號(hào)作為數(shù)組序號(hào)

57、 sigset_t blocked, real_blocked; 被阻塞信號(hào)的掩碼,每種信號(hào)類型對(duì)應(yīng)一個(gè)元素 struct sigpending pending; 維護(hù)本進(jìn)程中的未決信號(hào) sigset_t saved_sigmask; 保存信號(hào)掩碼 定義TIF_RESTORE_SIGMASK時(shí)恢復(fù)信號(hào)掩碼62task_struct信號(hào)處理相關(guān)數(shù)據(jù)結(jié)構(gòu)關(guān)系圖6364System V IPC概述 IPC資源 表示單獨(dú)的消息隊(duì)列、共享內(nèi)存或信號(hào)量集合 具有相同類型的接口函數(shù) 信號(hào)量集合 實(shí)現(xiàn)進(jìn)程同步 消息隊(duì)列以異步方式為通信頻繁、但數(shù)據(jù)量少的進(jìn)程通信提供服務(wù) 共享主存為數(shù)據(jù)量大的進(jìn)程間通信提供服務(wù)

58、共同點(diǎn) 通過(guò) System V IPC對(duì)象通信時(shí),需傳遞該對(duì)象的唯一IPC標(biāo)識(shí)符 訪問(wèn)System V IPC對(duì)象時(shí)必須經(jīng)過(guò)許可檢驗(yàn) System V IPC對(duì)象的訪問(wèn)權(quán)限由對(duì)象創(chuàng)建者設(shè)置65IPC對(duì)象標(biāo)識(shí)符與IPC鍵 IPC標(biāo)識(shí)符 由內(nèi)核分配給IPC對(duì)象,在系統(tǒng)內(nèi)部唯一 IPC對(duì)象標(biāo)識(shí)符的獲?。篨XXget() 將IPC鍵傳遞給以sys_打頭的內(nèi)核函數(shù),并為用戶分配一個(gè)與IPC對(duì)象相對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu) 返回一個(gè)32位IPC標(biāo)識(shí)符,進(jìn)程使用此標(biāo)識(shí)符對(duì)該資源進(jìn)行訪問(wèn) IPC鍵 IPC對(duì)象的外部表示,可由程序員選擇 如果鍵是公用的,則系統(tǒng)中所有進(jìn)程通過(guò)權(quán)限檢查后,均可找到和訪問(wèn)相應(yīng)IPC對(duì)象 每個(gè)進(jìn)程

59、都可建立一個(gè)鍵值為IPC_PRIVATE的私有IPC對(duì)象66IPC鍵的創(chuàng)建 創(chuàng)建函數(shù) key_t ftok( char * filename, int id); 功能說(shuō)明 將一個(gè)現(xiàn)存文件名(對(duì)應(yīng)文件必須是可訪問(wèn)的)和一個(gè)整數(shù)標(biāo)識(shí)符id轉(zhuǎn)換成一個(gè)key_t值 在Linux系統(tǒng)中,調(diào)用該函數(shù)時(shí),系統(tǒng)將該文件的索引節(jié)點(diǎn)號(hào)取出,并在前面加上子序號(hào),從而得到key_t返回值IPC資源的全局定義v消息隊(duì)列 msgid_ds : 16個(gè) 定義位置:/proc/sys/kernel/msgmniv共享內(nèi)存 shmid_ds : 4096個(gè) 定義位置:/proc/sys/kernel/shmmniv信號(hào)量 se

60、mid_ds:128個(gè) 定義位置:/proc/sys/kernel/sem6768System V IPC的基本操作 操作函數(shù)(XXX代表msg、sem、shm三者之一) XXXget():獲得IPC標(biāo)識(shí)符 XXXctl():控制IPC資源 操作模式 先通過(guò)XXXget()創(chuàng)建一個(gè)IPC資源,返回IPC標(biāo)識(shí)符 隨后操作均以IPC資源標(biāo)識(shí)符為參數(shù),對(duì)相應(yīng)IPC資源進(jìn)行操作 其他進(jìn)程可通過(guò)XXXget()獲取已有的IPC資源標(biāo)識(shí)符(權(quán)限允許的話),并對(duì)其操作請(qǐng)求IPC標(biāo)識(shí)符時(shí)返回的錯(cuò)誤碼69錯(cuò)誤碼錯(cuò)誤碼說(shuō)明說(shuō)明EACCESS進(jìn)程沒(méi)有適當(dāng)?shù)脑L問(wèn)權(quán)限進(jìn)程沒(méi)有適當(dāng)?shù)脑L問(wèn)權(quán)限EEXIST進(jìn)程試圖創(chuàng)建一個(gè)和已有關(guān)鍵字相同的進(jìn)程試圖創(chuàng)建一個(gè)和已有關(guān)鍵字相同的IPC資源資源EINVAL在在XXXget()函數(shù)中

溫馨提示

  • 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)論