版權(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)程間通信概述 管道通信 信號(hào) 共享內(nèi)存 消息隊(duì)列,8/1/2020,1,1、進(jìn)程間通信概述,進(jìn)程間通信有如下一些目的: 數(shù)據(jù)傳輸:一個(gè)進(jìn)程需要將它的數(shù)據(jù)發(fā)送給另一個(gè)進(jìn)程,發(fā)送的數(shù)據(jù)量在一個(gè)字節(jié)到幾兆字節(jié)之間。 共享數(shù)據(jù):多個(gè)進(jìn)程想要操作共享數(shù)據(jù),一個(gè)進(jìn)程對(duì)共享數(shù)據(jù)的修改,別的進(jìn)程應(yīng)該立刻看到。 通知事件:一個(gè)進(jìn)程需要向另一個(gè)或一組進(jìn)程發(fā)送消息,通知它(它們)發(fā)生了某種事件(如進(jìn)程終止時(shí)要通知父進(jìn)程)。 資源共享:多個(gè)進(jìn)程之間共享同樣的資源。為了作到這一點(diǎn),需要內(nèi)核提供鎖和同步機(jī)制。 進(jìn)程控制:有些進(jìn)程希望完全控制另一個(gè)進(jìn)程的執(zhí)行(如Debug進(jìn)程),此時(shí)控制進(jìn)程希望能夠
2、攔截另一個(gè)進(jìn)程的所有陷入和異常,并能夠及時(shí)知道它的狀態(tài)改變。,8/1/2020,2,linux進(jìn)程間通信(IPC)由以下幾部分發(fā)展而來(lái): 早期UNIX進(jìn)程間通信、基于System V進(jìn)程間通信、基于Socket進(jìn)程間通信和POSIX進(jìn)程間通信。 UNIX進(jìn)程間通信方式包括:管道、FIFO、信號(hào)。 System V進(jìn)程間通信方式包括:System V消息隊(duì)列、System V信號(hào)燈、System V共享內(nèi)存。 POSIX進(jìn)程間通信包括:posix消息隊(duì)列、posix信號(hào)燈、posix共享內(nèi)存。,8/1/2020,3,現(xiàn)在linux使用的進(jìn)程間通信方式: (1)管道(pipe)和有名管道(FIFO
3、) (2)信號(hào)(signal) (3)消息隊(duì)列 (4)共享內(nèi)存 (5)信號(hào)量 (6)套接字(socket),8/1/2020,4,2、管道通信,普通的Linux shell都允許重定向,而重定向使用的就是管道。例如: ps | grep vsftpd 管道是單向的、先進(jìn)先出的、無(wú)結(jié)構(gòu)的、固定大小的字節(jié)流,它把一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸出和另一個(gè)進(jìn)程的標(biāo)準(zhǔn)輸入連接在一起。寫(xiě)進(jìn)程在管道的尾端寫(xiě)入數(shù)據(jù),讀進(jìn)程在管道的首端讀出數(shù)據(jù)。數(shù)據(jù)讀出后將從管道中移走,其它讀進(jìn)程都不能再讀到這些數(shù)據(jù)。管道提供了簡(jiǎn)單的流控制機(jī)制。進(jìn)程試圖讀空管道時(shí),在有數(shù)據(jù)寫(xiě)入管道前,進(jìn)程將一直阻塞。同樣,管道已經(jīng)滿時(shí),進(jìn)程再試圖寫(xiě)管道,在
4、其它進(jìn)程從管道中移走數(shù)據(jù)之前,寫(xiě)進(jìn)程將一直阻塞。 管道主要用于不同進(jìn)程間通信。,8/1/2020,5,2.1 管道創(chuàng)建與關(guān)閉,創(chuàng)建一個(gè)簡(jiǎn)單的管道,可以使用系統(tǒng)調(diào)用pipe( )。它接受一個(gè)參數(shù),也就是一個(gè)包括兩個(gè)整數(shù)的數(shù)組。如果系統(tǒng)調(diào)用成功,此數(shù)組將包括管道使用的兩個(gè)文件描述符。創(chuàng)建一個(gè)管道之后,一般情況下進(jìn)程將產(chǎn)生一個(gè)新的進(jìn)程。 系統(tǒng)調(diào)用:pipe( ); 原型:int pipe(int fd2); 返回值:如果系統(tǒng)調(diào)用成功,返回0。如果系統(tǒng)調(diào)用失敗返回- 1: errno = EMFILE (沒(méi)有空閑的文件描述符) EMFILE (系統(tǒng)文件表已滿) EFAULT (fd數(shù)組無(wú)效),8/1/
5、2020,6,注意:fd0 用于讀取管道,fd1 用于寫(xiě)入管道。,圖1 linux中管道與文件描述符的關(guān)系,8/1/2020,7,#include #include #include #include int main() int pipe_fd2; if(pipe(pipe_fd)0) printf(pipe create errorn); return -1; else printf(pipe create successn); close(pipe_fd0); close(pipe_fd1); ,8/1/2020,8,2.2 管道讀寫(xiě),管道主要用于不同進(jìn)程間通信。實(shí)際上,通常先創(chuàng)建一個(gè)管
6、道,再通過(guò)fork函數(shù)創(chuàng)建一個(gè)子進(jìn)程。,圖2 父子進(jìn)程管道的文件描述符對(duì)應(yīng)關(guān)系,8/1/2020,9,子進(jìn)程寫(xiě)入和父進(jìn)程讀的命名管道:,圖 3 關(guān)閉父進(jìn)程fd1 和 子進(jìn)程0,8/1/2020,10,2.3 管道讀寫(xiě)注意事項(xiàng),可以通過(guò)打開(kāi)兩個(gè)管道來(lái)創(chuàng)建一個(gè)雙向的管道。但需要在子進(jìn)程中正確地設(shè)置文件描述符。 必須在系統(tǒng)調(diào)用fork( )中調(diào)用pipe( ),否則子進(jìn)程將不會(huì)繼承文件描述符。 當(dāng)使用半雙工管道時(shí),任何關(guān)聯(lián)的進(jìn)程都必須共享一個(gè)相關(guān)的祖先進(jìn)程。因?yàn)楣艿来嬖谟谙到y(tǒng)內(nèi)核之中,所以任何不在創(chuàng)建管道的進(jìn)程的祖先進(jìn)程之中的進(jìn)程都將無(wú)法尋址它。而在命名管道中卻不是這樣。,8/1/2020,11,2
7、.4 標(biāo)準(zhǔn)流管道,與linux中文件操作有文件流的標(biāo)準(zhǔn)I/O一樣,管道的操作也支持基于文件流的模式。接口函數(shù)如下 庫(kù)函數(shù):popen(); 原型: FILE *popen ( char *command, char *type); 返回值:如果成功,返回一個(gè)新的文件流。如果無(wú)法創(chuàng)建進(jìn)程或者管道,返回NULL。 管道中數(shù)據(jù)流的方向是由第二個(gè)參數(shù)type控制的。此參數(shù)可以是r或者w,分別代表讀或?qū)?。但不能同時(shí)為讀和寫(xiě)。在Linux系統(tǒng)下,管道將會(huì)以參數(shù)type中第一個(gè)字符代表的方式打開(kāi)。所以,如果你在參數(shù)type中寫(xiě)入rw,管道將會(huì)以讀的方式打開(kāi)。,8/1/2020,12,使用popen()創(chuàng)建的
8、管道必須使用pclose( )關(guān)閉。其實(shí),popen/pclose和標(biāo)準(zhǔn)文件輸入/輸出流中的fopen()/fclose()十分相似。 庫(kù)函數(shù):pclose(); 原型:int pclose( FILE *stream ); 返回值:返回調(diào)用狀態(tài)。,8/1/2020,13,#include #include #include #include #define BUFSIZE 1024 int main() FILE *fp; char *cmd = ps -ef; char bufBUFSIZE; bufBUFSIZE = 0; if(fp=popen(cmd,r)=NULL) perror(
9、popen); while(fgets(buf,BUFSIZE,fp)!=NULL) printf(%s,buf); pclose(fp); exit(0); ,8/1/2020,14,命名管道(FIFO),基本概念 命名管道和一般的管道基本相同,但也有一些顯著的不同: 命名管道是在文件系統(tǒng)中作為一個(gè)特殊的設(shè)備文件而存在的。 不同祖先的進(jìn)程之間可以通過(guò)管道共享數(shù)據(jù)。 當(dāng)共享管道的進(jìn)程執(zhí)行完所有的I/O操作以后,命名管道將繼續(xù)保存在文件系統(tǒng)中以便以后使用。 管道只能由相關(guān)進(jìn)程使用,它們共同的祖先進(jìn)程創(chuàng)建了管道。但是,通過(guò)FIFO,不相關(guān)的進(jìn)程也能交換數(shù)據(jù)。,8/1/2020,15,命名管道創(chuàng)建與
10、操作,名管道創(chuàng)建 #include #include int mkfifo(const char *pathname, mode_t mode) ; 返回:若成功則為0,若出錯(cuò)則為 -1 一旦已經(jīng)用mkfifo創(chuàng)建了一個(gè)FIFO,就可用open打開(kāi)它。確實(shí),一般的文件I/O函數(shù)(close、read、write、unlink等)都可用于FIFO。,8/1/2020,16,當(dāng)打開(kāi)一個(gè)FIFO時(shí),非阻塞標(biāo)志(O_NONBLOCK)產(chǎn)生下列影響: (1) 在一般情況中(沒(méi)有說(shuō)明O_NONBLOCK),只讀打開(kāi)要阻塞到某個(gè)其他進(jìn)程為寫(xiě)打開(kāi)此FIFO。類(lèi)似,為寫(xiě)而打開(kāi)一個(gè)FIFO要阻塞到某個(gè)其他進(jìn)程為讀
11、而打開(kāi)它。 (2) 如果指定了O_NONBLOCK,則只讀打開(kāi)立即返回。但是,如果沒(méi)有進(jìn)程已經(jīng)為讀而打開(kāi)一個(gè)FIFO,那么只寫(xiě)打開(kāi)將出錯(cuò)返回,其errno是ENXIO。 類(lèi)似于管道,若寫(xiě)一個(gè)尚無(wú)進(jìn)程為讀而打開(kāi)的FIFO,則產(chǎn)生信號(hào)SIGPIPE。若某個(gè)FIFO的最后一個(gè)寫(xiě)進(jìn)程關(guān)閉了該FIFO,則將為該FIFO的讀進(jìn)程產(chǎn)生一個(gè)文件結(jié)束標(biāo)志。,8/1/2020,17,FIFO相關(guān)出錯(cuò)信息: EACCES (無(wú)存取權(quán)限) EEXIST (指定文件不存在) ENAMETOOLONG (路徑名太長(zhǎng)) ENOENT (包含的目錄不存在) ENOSPC (文件系統(tǒng)剩余空間不足) ENOTDIR (文件路徑無(wú)
12、效) EROFS (指定的文件存在于只讀文件系統(tǒng)中),8/1/2020,18,信號(hào)通信,信號(hào)概述 信號(hào)是軟件中斷。信號(hào)(signal)機(jī)制是Unix系統(tǒng)中最為古老的進(jìn)程之間的通信機(jī)制。它用于在一個(gè)或多個(gè)進(jìn)程之間傳遞異步信號(hào)。 很多條件可以產(chǎn)生一個(gè)信號(hào)。 當(dāng)用戶按某些終端鍵時(shí),產(chǎn)生信號(hào)。在終端上按DELETE鍵通常產(chǎn)生中斷信號(hào)(SIGINT)。這是停止一個(gè)已失去控制程序的方法。(第11章將說(shuō)明此信號(hào)可被映射為終端上的任一字符。) 硬件異常產(chǎn)生信號(hào):除數(shù)為0、無(wú)效的存儲(chǔ)訪問(wèn)等等。這些條件通常由硬件檢測(cè)到,并將其通知內(nèi)核。然后內(nèi)核為該條件發(fā)生時(shí)正在運(yùn)行的進(jìn)程產(chǎn)生適當(dāng)?shù)男盘?hào)。例如,對(duì)執(zhí)行一個(gè)無(wú)效存儲(chǔ)訪
13、問(wèn)的進(jìn)程產(chǎn)生一個(gè)SIGSEGV。,8/1/2020,19,進(jìn)程用kill (2)函數(shù)可將信號(hào)發(fā)送給另一個(gè)進(jìn)程或進(jìn)程組。自然,有些限制:接收信號(hào)進(jìn)程和發(fā)送信號(hào)進(jìn)程的所有者必須相同,或發(fā)送信號(hào)進(jìn)程的所有者必須是超級(jí)用戶。 用戶可用kill (1)命令將信號(hào)發(fā)送給其他進(jìn)程。此程序是kill函數(shù)的界面。常用此命令終止一個(gè)失控的后臺(tái)進(jìn)程。 當(dāng)檢測(cè)到某種軟件條件已經(jīng)發(fā)生,并將其通知有關(guān)進(jìn)程時(shí)也產(chǎn)生信號(hào)。這里并不是指硬件產(chǎn)生條件(如被0除),而是軟件條件。例如SIGURG (在網(wǎng)絡(luò)連接上傳來(lái)非規(guī)定波特率的數(shù)據(jù))、SIGPIPE (在管道的讀進(jìn)程已終止后一個(gè)進(jìn)程寫(xiě)此管道),以及SIGALRM(進(jìn)程所設(shè)置的鬧鐘
14、時(shí)間已經(jīng)超時(shí))。,8/1/2020,20,內(nèi)核為進(jìn)程生產(chǎn)信號(hào),來(lái)響應(yīng)不同的事件,這些事件就是信號(hào)源。主要的信號(hào)源如下: 異常:進(jìn)程運(yùn)行過(guò)程中出現(xiàn)異常; 其它進(jìn)程:一個(gè)進(jìn)程可以向另一個(gè)或一組進(jìn)程發(fā)送信號(hào); 終端中斷:Ctrl-C,Ctrl-等; 作業(yè)控制:前臺(tái)、后臺(tái)進(jìn)程的管理; 分配額:CPU超時(shí)或文件大小突破限制; 通知:通知進(jìn)程某事件發(fā)生,如I/O就緒等; 報(bào)警:計(jì)時(shí)器到期。,8/1/2020,21,Linux 中的信號(hào):,1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE 9)
15、SIGKILL 10)SIGUSR1 11) SIGSEGV12) SIGUSR2 13)SIGPIPE 14)SIGALRM15) SIGTERM17) SIGCHLD 18)SIGCONT 19)SIGSTOP20) SIGTSTP21) SIGTTIN 22)SIGTTOU 23)SIGURG24) SIGXCPU25) SIGXFSZ 26)SIGVTALRM 27)SIGPROF 28) SIGWINCH 29)SIGIO 30)SIGPWR,8/1/2020,22,下面是幾個(gè)常見(jiàn)的信號(hào)。 SIGHUP: 從終端上發(fā)出的掛起信號(hào); SIGINT: 來(lái)自鍵盤(pán)的中斷信號(hào)(Ctrl-C);
16、 SIGQUIT:來(lái)自鍵盤(pán)的退出信號(hào)(Ctrl-); SIGFPE: 浮點(diǎn)異常信號(hào)(例如浮點(diǎn)運(yùn)算溢出); SIGKILL:該信號(hào)結(jié)束接收信號(hào)的進(jìn)程; SIGALRM:進(jìn)程的定時(shí)器到期時(shí),發(fā)送該信號(hào); SIGTERM:中止信號(hào);kill的默認(rèn)發(fā)出信號(hào); SIGCHLD:標(biāo)識(shí)子進(jìn)程停止或結(jié)束的信號(hào); SIGSTOP:來(lái)自鍵盤(pán)(Ctrl-Z)或調(diào)試程序的停止執(zhí)行信號(hào) ,8/1/2020,23,可以要求系統(tǒng)在某個(gè)信號(hào)出現(xiàn)時(shí)按照下列三種方式中的一種進(jìn)行操作。 (1) 忽略此信號(hào)。大多數(shù)信號(hào)都可使用這種方式進(jìn)行處理,但有兩種信號(hào)卻決不能被忽略。它們是:SIGKILL和SIGSTOP。這兩種信號(hào)不能被忽略的
17、原因是:它們向超級(jí)用戶提供一種使進(jìn)程終止或停止的可靠方法。另外,如果忽略某些由硬件異常產(chǎn)生的信號(hào)(例如非法存儲(chǔ)訪問(wèn)或除以0),則進(jìn)程的行為是未定義的。 (2) 捕捉信號(hào)。為了做到這一點(diǎn)要通知內(nèi)核在某種信號(hào)發(fā)生時(shí),調(diào)用一個(gè)用戶函數(shù)。在用戶函數(shù)中,可執(zhí)行用戶希望對(duì)這種事件進(jìn)行的處理。如果捕捉到SIGCHLD信號(hào),則表示子進(jìn)程已經(jīng)終止,所以此信號(hào)的捕捉函數(shù)可以調(diào)用waitpid以取得該子進(jìn)程的進(jìn)程ID以及它的終止?fàn)顟B(tài)。 (3) 執(zhí)行系統(tǒng)默認(rèn)動(dòng)作。對(duì)大多數(shù)信號(hào)的系統(tǒng)默認(rèn)動(dòng)作是終止該進(jìn)程。,8/1/2020,24,每一個(gè)信號(hào)都有一個(gè)缺省動(dòng)作,它是當(dāng)進(jìn)程沒(méi)有給這個(gè)信號(hào)指定處理程序時(shí),內(nèi)核對(duì)信號(hào)的處理。有5
18、種缺省的動(dòng)作: 異常終止(abort):在進(jìn)程的當(dāng)前目錄下,把進(jìn)程的地址空間內(nèi)容、寄存器內(nèi)容保存到一個(gè)叫做core的文件中,而后終止進(jìn)程。 退出(exit):不產(chǎn)生core文件,直接終止進(jìn)程。 忽略(ignore):忽略該信號(hào)。 停止(stop):掛起該進(jìn)程。 繼續(xù)(continue):如果進(jìn)程被掛起,則恢復(fù)進(jìn)程的運(yùn)行。否則,忽略信號(hào)。,8/1/2020,25,3.2 信號(hào)發(fā)送與捕捉,3.2.1 kill()和raise() kill()不僅可以中止進(jìn)程,也可以向進(jìn)程發(fā)送其他信號(hào)。 與kill函數(shù)不同的是,raise()函數(shù)運(yùn)行向進(jìn)程自身發(fā)送信號(hào)。 #include #include int
19、kill(pid_t pid, int signo) ; int raise(int signo) ; 兩個(gè)函數(shù)返回:若成功則為0,若出錯(cuò)則為-1。,8/1/2020,26,kill的pid參數(shù)有四種不同的情況: pid 0 將信號(hào)發(fā)送給進(jìn)程ID為pid的進(jìn)程。 pid = 0 將信號(hào)發(fā)送給其進(jìn)程組ID等于發(fā)送進(jìn)程的進(jìn)程組ID,而且發(fā)送進(jìn)程有許可權(quán)向其發(fā)送信號(hào)的所有進(jìn)程。 pid 0 將信號(hào)發(fā)送給其進(jìn)程組ID等于pid絕對(duì)值,而且發(fā)送進(jìn)程有許可權(quán)向其發(fā)送信號(hào)的所有進(jìn)程。如上所述一樣,“所有進(jìn)程”并不包括系統(tǒng)進(jìn)程集中的進(jìn)程。 pid = -1 POSIX.1未定義此種情況。,8/1/2020,2
20、7,3.2.2 alarm和pause函數(shù),使用alarm函數(shù)可以設(shè)置一個(gè)時(shí)間值(鬧鐘時(shí)間),在將來(lái)的某個(gè)時(shí)刻該時(shí)間值會(huì)被超過(guò)。當(dāng)所設(shè)置的時(shí)間值被超過(guò)后,產(chǎn)生SIGALRM信號(hào)。如果不忽略或不捕捉此信號(hào),則其默認(rèn)動(dòng)作是終止該進(jìn)程。 #include unsigned int alarm(unsigned int seconds) ; 返回:0或以前設(shè)置的鬧鐘時(shí)間的余留秒數(shù),8/1/2020,28,參數(shù)seconds的值是秒數(shù),經(jīng)過(guò)了指定的seconds秒后會(huì)產(chǎn)生信號(hào)SIGALRM。 每個(gè)進(jìn)程只能有一個(gè)鬧鐘時(shí)間。如果在調(diào)用alarm時(shí),以前已為該進(jìn)程設(shè)置過(guò)鬧鐘時(shí)間,而且它還沒(méi)有超時(shí),則該鬧鐘時(shí)間
21、的余留值作為本次alarm函數(shù)調(diào)用的值返回。以前登記的鬧鐘時(shí)間則被新值代換。 如果有以前登記的尚未超過(guò)的鬧鐘時(shí)間,而且seconds值是0,則取消以前的鬧鐘時(shí)間,其余留值仍作為函數(shù)的返回值。,8/1/2020,29,pause函數(shù)使調(diào)用進(jìn)程掛起直至捕捉到一個(gè)信號(hào)。 #include int pause(void); 返回:-1,errno設(shè)置為EINTR 只有執(zhí)行了一個(gè)信號(hào)處理程序并從其返回時(shí),pause才返回。,8/1/2020,30,3.3 信號(hào)的處理,當(dāng)系統(tǒng)捕捉到某個(gè)信號(hào)時(shí),可以忽略該信號(hào)或是使用指定的處理函數(shù)來(lái)處理該信號(hào),或者使用系統(tǒng)默認(rèn)的方式。 信號(hào)處理的主要方法有兩種,一種是使用簡(jiǎn)
22、單的signal函數(shù),另一種是使用信號(hào)集函數(shù)組。,8/1/2020,31,3.3.1 signal(),#include void (*signal (int signo, void (*func)(int)(int) 返回:成功則為以前的信號(hào)處理函數(shù)指針,若出錯(cuò)則為SIG_ERR func的值是: (a)常數(shù)SIG_IGN,或(b)常數(shù)SIG_DFL,或(c)當(dāng)接到此信號(hào)后要調(diào)用的函數(shù)的地址。如果指定SIG_IGN ,則向內(nèi)核表示忽略此信號(hào)(有兩個(gè)信號(hào)SIGKILL和SIGSTOP不能忽略)。如果指定SIG_DFL,則表示接到此信號(hào)后的動(dòng)作是系統(tǒng)默認(rèn)動(dòng)作。當(dāng)指定函數(shù)地址時(shí),我們稱(chēng)此為捕捉此信
23、號(hào)。我們稱(chēng)此函數(shù)為信號(hào)處理程序(signal handler)或信號(hào)捕捉函數(shù)(signal-catching function)。,8/1/2020,32,3.3.2 信號(hào)集函數(shù)組,我們需要有一個(gè)能表示多個(gè)信號(hào)信號(hào)集(signal set)的數(shù)據(jù)類(lèi)型。將在sigprocmask()這樣的函數(shù)中使用這種數(shù)據(jù)類(lèi)型,以告訴內(nèi)核不允許發(fā)生該信號(hào)集中的信號(hào)。信號(hào)集函數(shù)組包含幾大模塊: 創(chuàng)建函數(shù)集、登記信號(hào)集、檢測(cè)信號(hào)集。,8/1/2020,33,圖4 信號(hào)操作一般流程,Sigemptyset Sigaddset ,Sigprocmask ,定義信號(hào)集,設(shè)置信號(hào)屏蔽位,sa_mask sa_handler
24、 sigaction ,Sigpending ,定義信號(hào)處理函數(shù),測(cè)試信號(hào),8/1/2020,34, 創(chuàng)建函數(shù)集,#include int sigemptyset(sigset_t * set) ; int sigfillset(sigset_t * set) ; int sigaddset(sigset_t * set,int signo) ; int sigdelset(sigset_t * set,int signo) ; 四個(gè)函數(shù)返回:若成功則為0,若出錯(cuò)則為-1 int sigismember(const sigset_t * set, int signo) ; 返回:
25、若真則為1,若假則為0。,8/1/2020,35,sigemptyset: 初始化信號(hào)集合為空。 sigfillset: 初始化信號(hào)集合為所有信號(hào)的集合。 sigaddset: 將指定信號(hào)添加到現(xiàn)存集中。 sigdelset: 從信號(hào)集中刪除指定信號(hào)。 sigismember: 查詢(xún)指定信號(hào)是否在信號(hào)集合中。,8/1/2020,36, 登記信號(hào)集,登記信號(hào)處理機(jī)主要用于決定進(jìn)程如何處理信號(hào)。首先要判斷出當(dāng)前進(jìn)程阻塞能不能傳遞給該信號(hào)的信號(hào)集。這首先使用sigprocmask函數(shù)判斷檢測(cè)或更改信號(hào)屏蔽字,然后使用sigaction函數(shù)改變進(jìn)程接受到特定信號(hào)之后的行為。,8/1/20
26、20,37,一個(gè)進(jìn)程的信號(hào)屏蔽字可以規(guī)定當(dāng)前阻塞而不能遞送給該進(jìn)程的信號(hào)集。調(diào)用函數(shù)sigprocmask可以檢測(cè)或更改(或兩者)進(jìn)程的信號(hào)屏蔽字。 # include int sigprocmask(int how, const sigset_t * set, sigset_t * oset) ; 返回:若成功則為0,若出錯(cuò)則為-1 oset是非空指針,進(jìn)程的當(dāng)前信號(hào)屏蔽字通過(guò)oset返回。其次,若set是一個(gè)非空指針,則參數(shù)how指示如何修改當(dāng)前信號(hào)屏蔽字。,8/1/2020,38,用sigprocmask更改當(dāng)前信號(hào)屏蔽字的方法,how參數(shù)設(shè)定: SIG_BLOCK該該進(jìn)程新的信號(hào)屏蔽字
27、是其當(dāng)前信號(hào)屏蔽字和set指向信號(hào)集的并集。set包含了我們希望阻塞的附加信號(hào)。 SIG_UNBLOCK該該進(jìn)程新的信號(hào)屏蔽字是其當(dāng)前信號(hào)屏蔽字和set所指向信號(hào)集的交集。set包含了我們希望解除阻塞的信號(hào)。 SIG_SETMASK該該進(jìn)程新的信號(hào)屏蔽是set指向的值。 如果set是個(gè)空指針,則不改變?cè)撨M(jìn)程的信號(hào)屏蔽字, how的值也無(wú)意義。,8/1/2020,39,sigaction函數(shù)的功能是檢查或修改(或兩者)與指定信號(hào)相關(guān)聯(lián)的處理動(dòng)作。此函數(shù)取代了UNIX早期版本使用的signal函數(shù)。 #include int sigaction(int signo, const struct si
28、gaction * act,struct sigaction * oact) ; 返回:若成功則為0,若出錯(cuò)則為- 1 參數(shù)signo是要檢測(cè)或修改具體動(dòng)作的信號(hào)的編號(hào)數(shù)。若act指針?lè)强?,則要修改其動(dòng)作。如果oact指針?lè)强?,則系統(tǒng)返回該信號(hào)的原先動(dòng)作。此函數(shù)使用下列結(jié)構(gòu): struct sigaction void (*sa_handler)(int signo); sigset_t sa_mask; int sa_flags; void (*sa_restore); ;,8/1/2020,40,sa_handler是一個(gè)函數(shù)指針,指定信號(hào)關(guān)聯(lián)函數(shù),可以是自定義處理函數(shù),還可以SIG_DF
29、L或 SIG_IGN。 sa_mask是一個(gè)信號(hào)集,它可以指定在信號(hào)處理程序執(zhí)行過(guò)程中哪些信號(hào)應(yīng)當(dāng)被阻塞。 sa_flags中包含許多標(biāo)志位,是對(duì)信號(hào)進(jìn)行處理的各種選項(xiàng)。具體如下: SA_NODEFERSA_NOMASK: 當(dāng)捕捉到此信號(hào)時(shí),在執(zhí)行其信號(hào)捕捉函數(shù)時(shí),系統(tǒng)不會(huì)自動(dòng)阻塞此信號(hào)。 SA_NOCLDSTOP: 進(jìn)程忽略子進(jìn)程產(chǎn)生的任何SIGSTOP、SIGTSTP、SIGTTIN和SIGTTOU信號(hào) SA_RESTART: 可讓重啟的系統(tǒng)調(diào)用重新起作用。 SA_ONESHOTSA_RESETHAND: 自定義信號(hào)只執(zhí)行一次,在執(zhí)行完畢后恢復(fù)信號(hào)的系統(tǒng)默認(rèn)動(dòng)作。,8/1/2020,41,
30、 檢測(cè)信號(hào)集,檢測(cè)信號(hào)是信號(hào)處理的后續(xù)步驟,但不是必須的。 sigpending函數(shù)運(yùn)行進(jìn)程檢測(cè)“未決”信號(hào)(進(jìn)程不清楚他的存在),并進(jìn)一步?jīng)Q定對(duì)他們做何處理。 sigpending返回對(duì)于調(diào)用進(jìn)程被阻塞不能遞送和當(dāng)前未決的信號(hào)集。 #include int sigpending(sigset_t * set) ; 返回:若成功則為0,若出錯(cuò)則為-1,8/1/2020,42,4、共享內(nèi)存,共享內(nèi)存區(qū)域是被多個(gè)進(jìn)程共享的一部分物理內(nèi)存。如果多個(gè)進(jìn)程都把該內(nèi)存區(qū)域映射到自己的虛擬地址空間,則這些進(jìn)程就都可以直接訪問(wèn)該共享內(nèi)存區(qū)域,從而可以通過(guò)該區(qū)域進(jìn)行通信。共享內(nèi)存是進(jìn)程間共享數(shù)據(jù)的
31、一種最快的方法,一個(gè)進(jìn)程向共享內(nèi)存區(qū)域?qū)懭肓藬?shù)據(jù),共享這個(gè)內(nèi)存區(qū)域的所有進(jìn)程就可以立刻看到其中的內(nèi)容。,8/1/2020,43,圖5 共享內(nèi)存原理示意圖,8/1/2020,44,共享內(nèi)存實(shí)現(xiàn)分為兩個(gè)步驟: 一、創(chuàng)建共享內(nèi)存,使用shmget函數(shù)。 二、映射共享內(nèi)存,將這段創(chuàng)建的共享內(nèi)存映射到具體的進(jìn)程空間去,使用shmat函數(shù)。,8/1/2020,45,系統(tǒng)調(diào)用:shmget( ) ; 原型:int shmget ( key_t key, int size, int shmflg ); 返回值:如果成功,返回共享內(nèi)存段標(biāo)識(shí)符。 如果失敗,則返回- 1: errno = EINVAL (無(wú)效的內(nèi)
32、存段大小) EEXIST (內(nèi)存段已經(jīng)存在,無(wú)法創(chuàng)建) EIDRM (內(nèi)存段已經(jīng)被刪除) ENOENT (內(nèi)存段不存在) EACCES (權(quán)限不夠) ENOMEM (沒(méi)有足夠的內(nèi)存來(lái)創(chuàng)建內(nèi)存段),8/1/2020,46,系統(tǒng)調(diào)用:shmat(); 原型:int shmat ( int shmid, char *shmaddr, int shmflg); 返回值:如果成功,則返回共享內(nèi)存段連接到進(jìn)程中的地址。 如果失敗,則返回- 1: errno = EINVAL (無(wú)效的IPC ID 值或者無(wú)效的地址) ENOMEM (沒(méi)有足夠的內(nèi)存) EACCES (存取權(quán)限不夠),8/1/2020,47,
33、當(dāng)一個(gè)進(jìn)程不在需要共享的內(nèi)存段時(shí),它將會(huì)把內(nèi)存段從其地址空間中脫離。 系統(tǒng)調(diào)用:shmdt(); 調(diào)用原型:int shmdt ( char *shmaddr ); 返回值:如果失敗,則返回- 1: errno = EINVAL (無(wú)效的連接地址),8/1/2020,48,5.消息隊(duì)列,消息隊(duì)列就是消息的一個(gè)鏈表,它允許一個(gè)或多個(gè)進(jìn)程向它寫(xiě)消息,一個(gè)或多個(gè)進(jìn)程從中讀消息。具有一定的FIFO的特性,但是可實(shí)現(xiàn)消息的隨即查詢(xún)。這些消息存在于內(nèi)核中,由“隊(duì)列ID”來(lái)標(biāo)識(shí)。 消息隊(duì)列的實(shí)現(xiàn)包括創(chuàng)建和打開(kāi)隊(duì)列、添加消息、讀取消息和控制消息隊(duì)列這四種操作。 msgget:創(chuàng)建和打開(kāi)隊(duì)列,其消息數(shù)量受系統(tǒng)限制
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年華能核電開(kāi)發(fā)有限公司所屬基層企業(yè)社會(huì)化招聘82人備考題庫(kù)及完整答案詳解1套
- 2026年北京國(guó)豐生科生物科技有限公司招聘?jìng)淇碱}庫(kù)及參考答案詳解一套
- 2026年中國(guó)化學(xué)工程第七建設(shè)有限公司瀘州分公司招聘?jìng)淇碱}庫(kù)及答案詳解1套
- 2026年廣州軟件學(xué)院專(zhuān)任教師招聘140人備考題庫(kù)及1套參考答案詳解
- 2026年成都陸港智匯科技服務(wù)有限公司關(guān)于面向社會(huì)公開(kāi)招聘成都市青白江區(qū)網(wǎng)格員的備考題庫(kù)參考答案詳解
- 2026年北京知行派教育科技有限公司招聘?jìng)淇碱}庫(kù)完整答案詳解
- 2026年包頭市眼科醫(yī)院面向社會(huì)招聘控制數(shù)工作人員備考題庫(kù)及答案詳解1套
- 2026年廣州市白云區(qū)24所公辦中小學(xué)招聘各科臨聘教師備考題庫(kù)及一套完整答案詳解
- 2026年中山市三鄉(xiāng)鎮(zhèn)大布小學(xué)招聘語(yǔ)文臨聘教師備考題庫(kù)及答案詳解參考
- 2026年中國(guó)特種飛行器研究所招聘?jìng)淇碱}庫(kù)及答案詳解1套
- 《漁業(yè)法》2025修訂解讀:新制度亮點(diǎn)及職責(zé)條例強(qiáng)化
- 【小學(xué)】【期末】家長(zhǎng)會(huì):孩子在學(xué)校的底氣【課件】
- 2025年煤礦井下電鉗工作業(yè)理論全國(guó)考試題庫(kù)(含答案)
- 云上(貴州)數(shù)據(jù)開(kāi)發(fā)有限公司招聘筆試題庫(kù)2026
- 2025廣東深圳市公安局第十三批招聘警務(wù)輔助人員2356人(公共基礎(chǔ)知識(shí))綜合能力測(cè)試題附答案解析
- 清洗吸污合同范本
- 信息系統(tǒng)安全設(shè)計(jì)方案
- 2025年廣東省繼續(xù)教育公需課人工智能賦能制造業(yè)高質(zhì)量發(fā)展試題及答案
- 考試中心托管合同范本
- 2025年項(xiàng)目管理崗位考試試題及答案
- 軍事能力考核題庫(kù)及答案
評(píng)論
0/150
提交評(píng)論