




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、LINUX 環(huán)境進(jìn)程間通信(全)目錄一.Linux 環(huán)境進(jìn)程間通信(一):管道及有名管道 31、 管道概述及相關(guān) API 應(yīng)用 31.1 管道相關(guān)的關(guān)鍵概念 31.2 管道的創(chuàng)建:31.3 管道的讀寫規(guī)則:31.4 管道應(yīng)用實(shí)例:81.5 管道的局限性 102、 有名管道概述及相關(guān) API 應(yīng)用 102.1 有名管道相關(guān)的關(guān)鍵概念 102.2 有名管道的創(chuàng)建 102.3 有名管道的打開規(guī)則 102.4 有名管道的讀寫規(guī)則 112.5 有名管道應(yīng)用實(shí)例 14小結(jié):143、 Linux 環(huán)境進(jìn)程間通信(二):信號(hào)(上)171、信號(hào)及信號(hào)來源 173.1 信號(hào)本質(zhì) 173.2 信號(hào)來源 172、信號(hào)
2、的種類 173.3 可靠信號(hào)與不可靠信號(hào) 173.4 實(shí)時(shí)信號(hào)與非實(shí)時(shí)信號(hào) 183、進(jìn)程對(duì)信號(hào)的響應(yīng) 184、信號(hào)的發(fā)送 195、信號(hào)的安裝(設(shè)置信號(hào)關(guān)聯(lián)動(dòng)作)206、信號(hào)集及信號(hào)集操作函數(shù):237、信號(hào)阻塞與信號(hào)未決 244、 Linux 環(huán)境進(jìn)程間通信(二):信號(hào)(下)261、信號(hào)生命周期 262、信號(hào)編程注意事項(xiàng) 27%) 防止不該丟失的信號(hào)丟失 27%) 程序的可移植性 272.3 程序的穩(wěn)定性 283、深入淺出:信號(hào)應(yīng)用實(shí)例 29實(shí)例一:信號(hào)發(fā)送及處理 29實(shí)例二:信號(hào)傳遞附加信息 30實(shí)例三:信號(hào)阻塞及信號(hào)集操作 32結(jié)束語:33四.Linux 環(huán)境進(jìn)程間通信(三):消息隊(duì)列 34
3、1、消息隊(duì)列基本概念 342、操作消息隊(duì)列 35消息隊(duì)列 API363、消息隊(duì)列的限制 384、消息隊(duì)列應(yīng)用實(shí)例 39小結(jié):41五.Linux 環(huán)境進(jìn)程間通信(四):信號(hào)燈 441、信號(hào)燈概述 442、Linux 信號(hào)燈 443、信號(hào)燈與內(nèi)核 444、操作信號(hào)燈 455、信號(hào)燈的限制 476、競(jìng)爭(zhēng)問題 487、信號(hào)燈應(yīng)用實(shí)例 48六.Linux 環(huán)境進(jìn)程間通信(五):共享內(nèi)存(上)531、內(nèi)核怎樣保證各個(gè)進(jìn)程尋址到同一個(gè)共享內(nèi)存區(qū)域的內(nèi)存頁面 532、mmap()及其相關(guān)系統(tǒng)調(diào)用 5446)mmap()系統(tǒng)調(diào)用形式 5446)系統(tǒng)調(diào)用 mmap()用于共享內(nèi)存的兩種方式 5446)系統(tǒng)調(diào)用 m
4、unmap()5546)系統(tǒng)調(diào)用 msync()553、mmap()范例 55范例 1:兩個(gè)進(jìn)程通過映射普通文件實(shí)現(xiàn)共享內(nèi)存通信 55范例 2:父子進(jìn)程通過匿名映射實(shí)現(xiàn)共享內(nèi)存 584、對(duì) mmap()返回地址的訪問 59結(jié)論 61七.Linux 環(huán)境進(jìn)程間通信(五):共享內(nèi)存(下)611、系統(tǒng) V 共享內(nèi)存原理 612、系統(tǒng) V 共享內(nèi)存 API623、系統(tǒng) V 共享內(nèi)存限制 634、系統(tǒng) V 共享內(nèi)存范例 63結(jié)論 65Linux環(huán)境進(jìn)程間通信(一):管道及有名管道1、管道概述及相關(guān) API 應(yīng)用管道相關(guān)的關(guān)鍵概念管道是 Linux 支持的最初 UnixIPC 形式之一,具有以下特點(diǎn):管道
5、是半雙工的,數(shù)據(jù)只能向一個(gè)方向流動(dòng);需要雙方通信時(shí),需要建立起兩個(gè)管道;只能用于父子進(jìn)程或者兄弟進(jìn)程之間(具有親緣關(guān)系的進(jìn)程);單獨(dú)構(gòu)成一種獨(dú)立的文件系統(tǒng):管道對(duì)于管道兩端的進(jìn)程而言,就是一個(gè)文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨(dú)構(gòu)成一種文件系統(tǒng),并且只存在與內(nèi)存中。數(shù)據(jù)的讀出和寫入:一個(gè)進(jìn)程向管道中寫的內(nèi)容被管道另一端的進(jìn)程讀出。寫入的內(nèi)容每次都添加在管道緩沖區(qū)的末尾,并且每次都是從緩沖區(qū)的頭部讀出數(shù)據(jù)。管道的創(chuàng)建:#includeintpipe(intfd2)該函數(shù)創(chuàng)建的管道的兩端處于一個(gè)進(jìn)程中間,在實(shí)際應(yīng)用中沒有太大意義,因此,一個(gè)進(jìn)程在由 pipe()創(chuàng)建管
6、道后,一般再 fork 一個(gè)子進(jìn)程,然后通過管道實(shí)現(xiàn)父子進(jìn)程間的通信(因此也不難推出,只要兩個(gè)進(jìn)程中存在親緣關(guān)系,這里的親緣關(guān)系指的是具有共同的祖先,都可以采用管道方式來進(jìn)行通信)。管道的讀寫規(guī)則:管道兩端可分別用描述字 fd0以及 fd1來描述,需要注意的是,管道的兩端是固定了任務(wù)的。即一端只能用于讀,由描述字 fd0表示,稱其為管道讀端;另一端則只能用于寫,由描述字 fd1來表示,稱其為管道寫端。如果試圖從管道寫端讀取數(shù)據(jù),或者向管道讀端寫入數(shù)據(jù)都將導(dǎo)致錯(cuò)誤發(fā)生。一般文件的 I/O 函數(shù)都可以用于管道,如 close、read、write 等等。從管道中讀取數(shù)據(jù):如果管道的寫端不存在,則認(rèn)
7、為已經(jīng)讀到了數(shù)據(jù)的末尾,讀函數(shù)返回的讀出字節(jié)數(shù)為 0;當(dāng)管道的寫端存在時(shí),如果請(qǐng)求的字節(jié)數(shù)目大于 PIPE_BUF 則返回管道中現(xiàn)有的數(shù)據(jù)字節(jié)數(shù),如果請(qǐng)求的字節(jié)數(shù)目不大于 PIPE_BUF 則返回管道中現(xiàn)有數(shù)據(jù)字節(jié)數(shù)(此時(shí),管道中數(shù)據(jù)量小于請(qǐng)求的數(shù)據(jù)量);或者返回請(qǐng)求的字節(jié)數(shù)(此時(shí),管道中數(shù)據(jù)量不小于請(qǐng)求的數(shù)據(jù)量)。注:(PIPE_BUFBinclude/linux/limits.h 中定義,不同的內(nèi)核版本可能會(huì)有所不同。Posix.1 要求 PIPE_BUF1 少為 512 字節(jié),redhat7.2 中為 4096)。3/65關(guān)于管道的讀規(guī)則驗(yàn)證:/*readtest.c*/#include
8、#include#includemain()(intpipe_fd2;pid_tpid;charr_buf100;charw_buf4;char*p_wbuf;intr_num;intcmd;memset(r_buf,0,sizeof(r_buf);memset(w_buf,0,sizeof(r_buf);p_wbuf=w_buf;if(pipe(pipe_fd)0)(close(pipe_fd0);/readstrcpy(w_buf,111);if(write(pipe_fd1,w_buf,4)!=-1)printf(parentwriteovern);close(pipe_fd1);/wr
9、iteprintf(parentclosefd1overn);sleep(10);/*程序輸出結(jié)果:parentwriteoverparentclosefd1overreadnumis4thedatareadfromthepipeis111附加結(jié)論:管道寫端關(guān)閉后,寫入的數(shù)據(jù)將一直存在,直到讀出為止*I向管道中寫入數(shù)據(jù):向管道中寫入數(shù)據(jù)時(shí),linux 將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會(huì)試圖向管道寫入數(shù)據(jù)。如果讀進(jìn)程不讀走管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將一直阻塞。注:只有在管道的讀端存在時(shí),向管道中寫入數(shù)據(jù)才有意義。否則,向管道中寫入數(shù)據(jù)的進(jìn)程將收到內(nèi)核傳來的 SIFPIP
10、E 言號(hào),應(yīng)用程序可以處理該信號(hào),也可以忽略(默認(rèn)動(dòng)作則是應(yīng)用程序終止)。對(duì)管道的寫規(guī)則的驗(yàn)證 1:寫端對(duì)讀端存在的依賴性#include#includemain()intpipe_fd2;pid_tpid;charr_buf4;char*w_buf;intwritenum;intcmd;memset(r_buf,0,sizeof(r_buf);if(pipe(pipe_fd)0)(sleep(1);等待子進(jìn)程完成關(guān)閉讀端的操作close(pipe_fd0);/writew_buf=111;if(writenum=write(pipe_fd1,w_buf,4)=-1)printf(writet
11、opipeerrorn);elseprintf(thebyteswritetopipeis%dn,writenum);close(pipe_fd1);)則輸出結(jié)果為:Brokenpipe,原因就是該管道以及它的所有 fork()產(chǎn)物的讀端都已經(jīng)被關(guān)閉。如果在父進(jìn)程中保留讀端,即在寫完 pipe 后,再關(guān)閉父進(jìn)程的讀端,也會(huì)正常寫入 pipe,讀者可自己驗(yàn)證一下該結(jié)論。因此,在向管道寫入數(shù)據(jù)時(shí),至少應(yīng)該存在某一個(gè)進(jìn)程,其中管道讀端沒有被關(guān)閉,否則就會(huì)出現(xiàn)上述錯(cuò)誤(管道斷裂,進(jìn)程收到了 SIGPIPE 言號(hào),默認(rèn)動(dòng)作是進(jìn)程終止)對(duì)管道的寫規(guī)則的驗(yàn)證 2:linux 不保證寫管道的原子性驗(yàn)證#inc
12、lude#include#includemain(intargc,char*argv)(intpipe_fd2;pid_tpid;charr_buf4096;charw_buf4096*2;intwritenum;intrnum;memset(r_buf,0,sizeof(r_buf);if(pipe(pipe_fd)0)(close(pipe_fd0);/writememset(r_buf,0,sizeof(r_buf);if(writenum=write(pipe_fd1,w_buf,1024)=-1)printf(writetopipeerrorn);elseprintf(thebyte
13、swritetopipeis%dn,writenum);writenum=write(pipe_fd1,w_buf,4096);close(pipe_fd1);輸出結(jié)果:thebyteswritetopipe1000thebyteswritetopipe1000注意,此行輸出說明了寫入的非原子性thebyteswritetopipe1000thebyteswritetopipe1000thebyteswritetopipe1000thebyteswritetopipe120/注意,此行輸出說明了寫入的非原子性thebyteswritetopipe0thebyteswritetopipe0結(jié)論:
14、寫入數(shù)目小于 4096 時(shí)寫入是非原子的!如果把父進(jìn)程中的兩次寫入字節(jié)數(shù)都改為 5000,則很容易得出下面結(jié)論:寫入管道的數(shù)據(jù)量大于 4096 字節(jié)時(shí),緩沖區(qū)的空閑空間將被寫入數(shù)據(jù)(補(bǔ)齊),直到寫完所有數(shù)據(jù)為止,如果沒有進(jìn)程讀數(shù)據(jù),則一直阻塞。1.4 管道應(yīng)用實(shí)例:實(shí)例一:用于 shell管道可用于輸入輸出重定向,它將一個(gè)命令的輸出直接定向到另一個(gè)命令的輸入。比如,當(dāng)在某個(gè) shell 程序(Bourneshell 或 Cshell 等)鍵入 whowc-l 后,相應(yīng) shell 程序?qū)?chuàng)建 who 以及 wc 兩個(gè)進(jìn)程和這兩個(gè)進(jìn)程間的管道。考慮下面的命令行:$kill-l 運(yùn)行結(jié)果見附$ki
15、ll-l|grepSIGRTMIN 運(yùn)行結(jié)果如下:30)SIGPWR31)SIGSYS32)SIGRTMIN33)SIGRTMIN+1實(shí)例二:用于具有親緣關(guān)系的進(jìn)程間通信下面例子給出了管道的具體應(yīng)用,父進(jìn)程通過管道發(fā)送一些命令給子進(jìn)程,子進(jìn)程解析命令,并根據(jù)命令作相應(yīng)處理。#include#includemain()intpipe_fd2;pid_tpid;charr_buf4;char*w_buf256;intchildexit=0;inti;intcmd;memset(r_buf,0,sizeof(r_buf);if(pipe(pipe_fd)0)/parent:sendcommandst
16、ochild(close(pipe_fd0);w_buf0=003;w_buf1=005;w_buf2=777;w_buf3=000;for(i=0;i4;i+)write(pipe_fd1,w_bufi,4);close(pipe_fd1);下面是子進(jìn)程的命令處理函數(shù)(特定于應(yīng)用):inthandle_cmd(intcmd)(if(cmd256)/supposechildonlysupport256commands(printf(child:invalidcommandn);return-1;printf(child:thecmdfromparentis%dn,cmd);return0;1.
17、5 管道的局限性管道的主要局限性正體現(xiàn)在它的特點(diǎn)上:只支持單向數(shù)據(jù)流;只能用于具有親緣關(guān)系的進(jìn)程之間;沒有名字;管道的緩沖區(qū)是有限的(管道制存在于內(nèi)存中,在管道創(chuàng)建時(shí),為緩沖區(qū)分配一個(gè)頁面大?。?;管道所傳送的是無格式字節(jié)流,這就要求管道的讀出方和寫入方必須事先約定好數(shù)據(jù)的格式,比如多少字節(jié)算作一個(gè)消息(或命令、或記錄)等等;2、有名管道概述及相關(guān) API 應(yīng)用有名管道相關(guān)的關(guān)鍵概念管道應(yīng)用的一個(gè)重大限制是它沒有名字,因此,只能用于具有親緣關(guān)系的進(jìn)程間通信,在有名管道(namedpipe 或 FIFO)提出后,該限制得到了克服。FIFO 不同于管道之處在于它提供一個(gè)路徑名與之關(guān)聯(lián),以 FIFO
18、的文件形式存在于文件系統(tǒng)中。這樣,即使與 FIFO 的創(chuàng)建進(jìn)程不存在親緣關(guān)系的進(jìn)程,只要可以訪問該路徑,就能夠彼此通過 FIFO 相互通信(能夠訪問該路徑的進(jìn)程以及 FIFO 的創(chuàng)建進(jìn)程之間),因此,通過 FIFO 不相關(guān)的進(jìn)程也能交換數(shù)據(jù)。值得注意的是,F(xiàn)IFO 嚴(yán)格遵循先進(jìn)先出(firstinfirstout),對(duì)管道及 FIFO 的讀總是從開始處返回?cái)?shù)據(jù),對(duì)它們的寫則把數(shù)據(jù)添加到末尾。它們不支持諸如 lseek()等文件定位操作。有名管道的創(chuàng)建#include#includeintmkfifo(constchar*pathname,mode_tmode)該函數(shù)的第一個(gè)參數(shù)是一個(gè)普通白路徑
19、名,也就是創(chuàng)建后 FIFO 的名字。第二個(gè)參數(shù)與打開普通文件的 open()函數(shù)中的 mode 參數(shù)相同。如果 mkfifo 的第一個(gè)參數(shù)是一個(gè)已經(jīng)存在的路徑名時(shí),會(huì)返回 EEXIST 錯(cuò)誤,所以一般典型的調(diào)用代碼首先會(huì)檢查是否返回該錯(cuò)誤,如果確實(shí)返回該錯(cuò)誤,那么只要調(diào)用打開 FIFO 的函數(shù)就可以了。一般文件的 I/O 函數(shù)都可以用于 FIFO,如 close、read、write 等等。有名管道的打開規(guī)則有名管道比管道多了一個(gè)打開操作:open。FIFO 的打開規(guī)則:如果當(dāng)前打開操作是為讀而打開 FIFO 時(shí),若已經(jīng)有相應(yīng)進(jìn)程為寫而打開該 FIFO,則當(dāng)前打開操作將成功返回;否則,可能阻塞
20、直到有相應(yīng)進(jìn)程為寫而打開該 FIFO(當(dāng)前打開操作設(shè)置了阻塞標(biāo)志);或者,成功返回(當(dāng)前打開操作沒有設(shè)置阻塞標(biāo)志)。如果當(dāng)前打開操作是為寫而打開 FIFO 時(shí), 如果已經(jīng)有相應(yīng)進(jìn)程為讀而打開該 FIFO,則當(dāng)前打開操作將成功返回;否則,可能阻塞直到有相應(yīng)進(jìn)程為讀而打開該 FIFO(當(dāng)前打開操作設(shè)置了阻塞標(biāo)志);或者,返回 ENXIO 錯(cuò)誤(當(dāng)前打開操作沒有設(shè)置阻塞標(biāo)志)。對(duì)打開規(guī)則的驗(yàn)證參見附 2。有名管道的讀寫規(guī)則從 FIFO 中讀取數(shù)據(jù):約定:如果一個(gè)進(jìn)程為了從 FIFO 中讀取數(shù)據(jù)而阻塞打開 FIFO,那么稱該進(jìn)程內(nèi)的讀操作為設(shè)置了阻塞標(biāo)志的讀操作。如果有進(jìn)程寫打開 FIFO,且當(dāng)前 F
21、IFO 內(nèi)沒有數(shù)據(jù),則對(duì)于設(shè)置了阻塞標(biāo)志的讀操作來說,將一直阻塞。對(duì)于沒有設(shè)置阻塞標(biāo)志讀操作來說則返回-1,當(dāng)前 errno 值為EAGAIN,提醒以后再試。對(duì)于設(shè)置了阻塞標(biāo)志的讀操作說,造成阻塞的原因有兩種:當(dāng)前 FIFO 內(nèi)有數(shù)據(jù),但有其它進(jìn)程在讀這些數(shù)據(jù);另外就是 FIFO 內(nèi)沒有數(shù)據(jù)。解阻塞的原因則是 FIFO 中有新的數(shù)據(jù)寫入,不論信寫入數(shù)據(jù)量的大小,也不論讀操作請(qǐng)求多少數(shù)據(jù)量。讀打開的阻塞標(biāo)志只對(duì)本進(jìn)程第一個(gè)讀操作施加作用,如果本進(jìn)程內(nèi)有多個(gè)讀操作序列,則在第一個(gè)讀操作被喚醒并完成讀操作后,其它將要執(zhí)行的讀操作將不再阻塞,即使在執(zhí)行讀操作時(shí),F(xiàn)IFO 中沒有數(shù)據(jù)也一樣(此時(shí),讀操作
22、返回 0)。如果沒有進(jìn)程寫打開 FIFO,則設(shè)置了阻塞標(biāo)志的讀操作會(huì)阻塞。注:如果 FIFO 中有數(shù)據(jù),則設(shè)置了阻塞標(biāo)志的讀操作不會(huì)因?yàn)?FIFO 中的字節(jié)數(shù)小于請(qǐng)求讀的字節(jié)數(shù)而阻塞,此時(shí),讀操作會(huì)返回 FIFO 中現(xiàn)有的數(shù)據(jù)量。向 FIFO 中寫入數(shù)據(jù):約定:如果一個(gè)進(jìn)程為了向 FIFO 中寫入數(shù)據(jù)而阻塞打開 FIFO,那么稱該進(jìn)程內(nèi)的寫操作為設(shè)置了阻塞標(biāo)志的寫操作。對(duì)于設(shè)置了阻塞標(biāo)志的寫操作:當(dāng)要寫入的數(shù)據(jù)量不大于 PIPE_BUFM,linux 將保證寫入的原子性。如果此時(shí)管道空閑緩沖區(qū)不足以容納要寫入的字節(jié)數(shù),則進(jìn)入睡眠,直到當(dāng)緩沖區(qū)中能夠容納要寫入的字節(jié)數(shù)時(shí),才開始進(jìn)行一次性寫操作。
23、當(dāng)要寫入的數(shù)據(jù)量大于 PIPE_BUF 時(shí),linux 將不再保證寫入的原子性。FIFO 緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會(huì)試圖向管道寫入數(shù)據(jù),寫操作在寫完所有請(qǐng)求寫的數(shù)據(jù)后返回。對(duì)于沒有設(shè)置阻塞標(biāo)志的寫操作:當(dāng)要寫入的數(shù)據(jù)量大于 PIPE_BUF 時(shí),linux 將不再保證寫入的原子性。在寫滿所有FIFO 空閑緩沖區(qū)后,寫操作返回。當(dāng)要寫入的數(shù)據(jù)量不大于 PIPE_BUF 時(shí),linux 將保證寫入的原子性。如果當(dāng)前 FIFO空閑緩沖區(qū)能夠容納請(qǐng)求寫入的字節(jié)數(shù),寫完后成功返回;如果當(dāng)前 FIFO 空閑緩沖區(qū)不能夠容納請(qǐng)求寫入的字節(jié)數(shù),則返回 EAGAIN 錯(cuò)誤,提醒以后再寫;對(duì) FIFO 讀寫規(guī)
24、則的驗(yàn)證:下面提供了兩個(gè)對(duì) FIFO 的讀寫程序,適當(dāng)調(diào)節(jié)程序中的很少地方或者程序的命令行參數(shù)就可以對(duì)各種 FIFO 讀寫規(guī)則進(jìn)行驗(yàn)證。程序 1:寫 FIFO 的程序#include#include#include#include#defineFIFO_SERVER/tmp/fifoservermain(intargc,char*argv)/參數(shù)為即將寫入的字節(jié)數(shù)intfd;charw_buf4096*2;intreal_wnum;memset(w_buf,0,4096*2);if(mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)0)&(errno!=EEXIST)
25、printf(cannotcreatefifoservern);if(fd=-1)if(errno=ENXIO)printf(openerror;noreadingprocessn);fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);/設(shè)置非阻塞標(biāo)志/fd=open(FIFO_SERVER,O_WRONLY);設(shè)置阻塞標(biāo)志real_wnum=write(fd,w_buf,2048);if(real_wnum=-1)if(errno=EAGAIN)printf(writetofifoerror;trylatern);elseprintf(realwritenu
26、mis%dn,real_wnum);real_wnum=write(fd,w_buf,5000);/5000 用于測(cè)試寫入字節(jié)大于 4096 時(shí)的非原子性real_wnum=write(fd,w_buf,4096);/4096 用于測(cè)試寫入字節(jié)不大于 4096 時(shí)的原子性if(real_wnum=-1)if(errno=EAGAIN)printf(trylatern);程序 2:與程序 1 一起測(cè)試寫 FIFO 的規(guī)則,第一個(gè)命令行參數(shù)是請(qǐng)求從 FIFO 讀出的字節(jié)#include#include#include#include#defineFIFO_SERVER/tmp/fifoserver
27、main(intargc,char*argv)charr_buf4096*2;intfd;intr_size;intret_size;r_size=atoi(argv1);printf(requredrealreadbytes%dn,r_size);memset(r_buf,0,sizeof(r_buf);fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0);/fd=open(FIFO_SERVER,O_RDONL0);/在此處可以把讀程序編譯成兩個(gè)不同版本:阻塞版本及非阻塞版本 if(fd=-1)printf(open%sforreaderrorn);exit
28、();while(1)memset(r_buf,0,sizeof(r_buf);ret_size=read(fd,r_buf,r_size);if(ret_size=-1)if(errno=EAGAIN)printf(nodataavlaiblen);printf(realreadbytes%dn,ret_size);sleep(1);pause();unlink(FIFO_SERVER);程序應(yīng)用說明:把讀程序編譯成兩個(gè)不同版本:阻塞讀版本:br以及非阻塞讀版本 nbr 把寫程序編譯成兩個(gè)四個(gè)版本:非阻塞且請(qǐng)求寫的字節(jié)數(shù)大于 PIPE_BUF 版本:nbwg非阻塞且請(qǐng)求寫的字節(jié)數(shù)不大于 PI
29、PE_BU 版本:版本 nbw阻塞且請(qǐng)求寫的字節(jié)數(shù)大于 PIPE_BUF 版本:bwg阻塞且請(qǐng)求寫的字節(jié)數(shù)不大于 PIPE_BUF 版本:版本 bw下面將使用 br、nbr、w 代替相應(yīng)程序中的阻塞讀、非阻塞讀驗(yàn)證阻塞寫操作:.當(dāng)請(qǐng)求寫入的數(shù)據(jù)量大于 PIPE_BUFM 的非原子性:onbr1000obwg.當(dāng)請(qǐng)求寫入的數(shù)據(jù)量不大于 PIPE_BUFM 的原子性:onbr1000obw 驗(yàn)證非阻塞寫操作:.當(dāng)請(qǐng)求寫入的數(shù)據(jù)量大于 PIPE_BUFM 的非原子性:onbr1000onbwg.請(qǐng)求寫入的數(shù)據(jù)量不大于 PIPE_BUF 寸的原子性:onbr1000onbw不管寫打開的阻塞標(biāo)志是否設(shè)置
30、,在請(qǐng)求寫入的字節(jié)數(shù)大于 4096 時(shí),都不保證寫入的原子性。但二者有本質(zhì)區(qū)別:對(duì)于阻塞寫來說,寫操作在寫滿 FIFO 的空閑區(qū)域后,會(huì)一直等待,直到寫完所有數(shù)據(jù)為止,請(qǐng)求寫入的數(shù)據(jù)最終都會(huì)寫入 FIFQ而非阻塞寫則在寫滿 FIFO 的空閑區(qū)域后,就返回(實(shí)際寫入白字節(jié)數(shù)),所以有些數(shù)據(jù)最終不能夠?qū)懭搿?duì)于讀操作的驗(yàn)證則比較簡(jiǎn)單,不再討論。2.5 有名管道應(yīng)用實(shí)例在驗(yàn)證了相應(yīng)的讀寫規(guī)則后,應(yīng)用實(shí)例似乎就沒有必要了。小結(jié):管道常用于兩個(gè)方面:(1)在 shell 中時(shí)常會(huì)用到管道(作為輸入輸入的重定向),在這種應(yīng)用方式下,管道的創(chuàng)建對(duì)于用戶來說是透明的;(2)用于具有親緣關(guān)系的進(jìn)程間通信,用戶自
31、己創(chuàng)建管道,并完成讀寫操作。FIFO 可以說是管道的推廣,克服了管道無名字的限制,使得無親緣關(guān)系的進(jìn)程同樣可以采用先進(jìn)先出的通信機(jī)制進(jìn)行通信。管道和 FIFO 的數(shù)據(jù)是字節(jié)流,應(yīng)用程序之間必須事先確定特定的傳輸協(xié)議”,采用傳播具有特定意義的消息。要靈活應(yīng)用管道及 FIFO,理解它們的讀寫規(guī)則是關(guān)鍵。kill-l 的運(yùn)行結(jié)果,顯示了當(dāng)前系統(tǒng)支持的所有信號(hào)1)SIGHUP2)SIGINT3)SIGQUIT4)SIGILL5)SIGTRAP6)SIGABRT7)SIGBUS8)SIGFPE9)SIGKILL0)SIGUSR111)SIGSEGV12)SIGUSR213)SIGPIPE14)SIGAL
32、RM15)SIGTERM17)SIGCHLD18)SIGCONT19)SIGSTOP20)SIGTSTP21)SIGTTIN22)SIGTTOU23)SIGURG24)SIGXCPU25)SIGXFSZ26)SIGVTALRM27)SIGPROF28)SIGWINCH29)SIGIO30)SIGPWR31)SIGSYS32)SIGRTMIN33)SIGRTMIN+1intret;ret=w_open(arg);switch(ret)(case0:34)SIGRTMIN+238)SIGRTMIN+642)SIGRTMIN+10SIGRTMIN+1450)SIGRTMAX-1354)SIGRTMA
33、X-958)SIGRTMAX-562)SIGRTMAX-135)SIGRTMIN+339)SIGRTMIN+743)SIGRTMIN+11SIGRTMIN+1551)SIGRTMAX-1255)SIGRTMAX-859)SIGRTMAX-463)SIGRTMAX36)SIGRTMIN+440)SIGRTMIN+8SIGRTMIN+1248)SIGRTMAX-1552)SIGRTMAX-1156)SIGRTMAX-760)SIGRTMAX-337)SIGRTMIN+541)SIGRTMIN+9SIGRTMIN+1349)SIGRTMAX-1453)SIGRTMAX-1057)SIGRTMAX-6
34、61)SIGRTMAX-2除了在此處用來說明管道應(yīng)用外,接下來的專題還要對(duì)這些信號(hào)分類討論。對(duì) FIFO 打開規(guī)則的驗(yàn)證(主要驗(yàn)證寫打開對(duì)讀打開的依賴性)#include#include#include#include#defineFIFO_SERVER/tmp/fifoserverinthandle_client(char*);main(intargc,char*argv)intr_rd;intw_fd;pid_tpid;if(mkfifo(FIFO_SERVER,O_CREAT|O_EXCL)0)&(errno!=EEXIST)printf(cannotcreatefifoserv
35、ern);handle_client(FIFO_SERVER);inthandle_client(char*arg)(printf(open%serrorn,arg);printf(noprocesshasthefifoopenforreadingn);return-1;case-1:(printf(somethingwrongwithopenthefifoexceptforENXIO);return-1;case1:(printf(openserverokn);return1;default:(printf(w_no_rreturn-n);return0;unlink(FIFO_SERVER
36、);intw_open(char*arg)0openerrorfornoreading-1openerrorforotherreasons1openok(if(open(arg,O_WRONLY|O_NONBLOCK,0)=-1)if(errno=ENXIO)(return0;elsereturn-1;return1;Linux環(huán)境進(jìn)程間通信(二):信號(hào)(上)1、信號(hào)及信號(hào)來源信號(hào)本質(zhì)信號(hào)是在軟件層次上對(duì)中斷機(jī)制的一種模擬,在原理上,一個(gè)進(jìn)程收到一個(gè)信號(hào)與處理器收到一個(gè)中斷請(qǐng)求可以說是一樣的。信號(hào)是異步的,一個(gè)進(jìn)程不必通過任何操作來等待信號(hào)的到達(dá),事實(shí)上,進(jìn)程也不知道信號(hào)到底什么時(shí)候到達(dá)。信號(hào)
37、是進(jìn)程間通信機(jī)制中唯一的異步通信機(jī)制,可以看作是異步通知,通知接收信號(hào)的進(jìn)程有哪些事情發(fā)生了。信號(hào)機(jī)制經(jīng)過 POSIX 實(shí)時(shí)擴(kuò)展后,功能更加強(qiáng)大,除了基本通知功能外,還可以傳遞附加信息。信號(hào)來源信號(hào)事件的發(fā)生有兩個(gè)來源:硬件來源(比如我們按下了鍵盤或者其它硬件故障);軟件來源,最常用發(fā)送信號(hào)的系統(tǒng)函數(shù)是 kill,raise,alarm 和 setitimer 以及 sigqueue 函數(shù), 軟件來源還包括一些非法運(yùn)算等操作。2、信號(hào)的種類可以從兩個(gè)不同的分類角度對(duì)信號(hào)進(jìn)行分類:(1)可靠性方面:可靠信號(hào)與不可靠信號(hào);(2)與時(shí)間的關(guān)系上:實(shí)時(shí)信號(hào)與非實(shí)時(shí)信號(hào)。在Linux 環(huán)境進(jìn)程間通信(一
38、):管道及有名管道的附 1 中列出了系統(tǒng)所支持的所有信號(hào)。可靠信號(hào)與不可靠信號(hào)“不可靠信號(hào)Linux 信號(hào)機(jī)制基本上是從 Unix 系統(tǒng)中繼承過來的。 早期 Unix 系統(tǒng)中的信號(hào)機(jī)制比較簡(jiǎn)單和原始, 后來在實(shí)踐中暴露出一些問題,因此,把那些建立在早期機(jī)制上的信號(hào)叫做不可靠信號(hào)”,信號(hào)值小于 SIGRTMIN(Redhat7.2 中,SIGRTMIN=32,SIGRTMAX=63 的信號(hào)都是不可靠信號(hào)。這就是不可靠信號(hào)”的來源。它的主要問題是:進(jìn)程每次處理信號(hào)后,就將對(duì)信號(hào)的響應(yīng)設(shè)置為默認(rèn)動(dòng)作。在某些情況下,將導(dǎo)致對(duì)信號(hào)的錯(cuò)誤處理;因此,用戶如果不希望這樣的操作,那么就要在信號(hào)處理函數(shù)結(jié)尾再一
39、次調(diào)用 signal。,重新安裝該信號(hào)。信號(hào)可能丟失,后面將對(duì)此詳細(xì)闡述。因此, 早期 unix 下的不可靠信號(hào)主要指的是進(jìn)程可能對(duì)信號(hào)做出錯(cuò)誤的反應(yīng)以及信號(hào)可能丟失。Linux 支持不可靠信號(hào),但是對(duì)不可靠信號(hào)機(jī)制做了改進(jìn):在調(diào)用完信號(hào)處理函數(shù)后,不必重新調(diào)用該信號(hào)的安裝函數(shù)(信號(hào)安裝函數(shù)是在可靠機(jī)制上的實(shí)現(xiàn))。因此,Linux 下的不可靠信號(hào)問題主要指的是信號(hào)可能丟失。可靠信號(hào)隨著時(shí)間的發(fā)展,實(shí)踐證明了有必要對(duì)信號(hào)的原始機(jī)制加以改進(jìn)和擴(kuò)充。所以,后來出現(xiàn)的各種 Unix 版本分別在這方面進(jìn)行了研究,力圖實(shí)現(xiàn)可靠信號(hào)。由于原來定義的信號(hào)已有許多應(yīng)用,不好再做改動(dòng),最終只好又新增加了一些信號(hào),
40、并在一開始就把它們定義為可靠信號(hào), 這些信號(hào)支持排隊(duì), 不會(huì)丟失。 同時(shí), 信號(hào)的發(fā)送和安裝也出現(xiàn)了新版本: 信號(hào)發(fā)送函數(shù) sigqueue()及信號(hào)安裝函數(shù) sigaction()。POSIX.4 對(duì)可靠信號(hào)機(jī)制做了標(biāo)準(zhǔn)化。但是,POSIX只對(duì)可靠信號(hào)機(jī)制應(yīng)具有的功能以及信號(hào)機(jī)制的對(duì)外接口做了標(biāo)準(zhǔn)化,對(duì)信號(hào)機(jī)制的實(shí)現(xiàn)沒有作具體的規(guī)定。信號(hào)值位于 SIGRTMIN 和 SIGRTMAX 之間的信號(hào)都是可靠信號(hào), 可靠信號(hào)克服了信號(hào)可能丟失的問題。Linux 在支持新版本的彳 t 號(hào)安裝函數(shù) sigation()以及信號(hào)發(fā)送函數(shù) sigqueue()的同時(shí),仍然支持早期的 signal()信號(hào)安
41、裝函數(shù),支持信號(hào)發(fā)送函數(shù) kill()。注:不要有這樣的誤解:由 sigqueue()發(fā)送、sigaction 安裝的信號(hào)就是可靠的。事實(shí)上,可靠信號(hào)是指后來添加的新信號(hào)(信號(hào)值位于 SIGRTMIN 及 SIGRTMAX 之間);不可靠信號(hào)是信號(hào)值小于 SIGRTMIN 的信號(hào)。信號(hào)的可靠與不可靠只與信號(hào)值有關(guān),與信號(hào)的發(fā)送及安裝函數(shù)無關(guān)。目前 linux 中的 signal()是通過 sigation()函數(shù)實(shí)現(xiàn)的,因此,即使通過 signal()安裝的信號(hào),在信號(hào)處理函數(shù)的結(jié)尾也不必再調(diào)用一次信號(hào)安裝函數(shù)。同時(shí),由 signal()安裝的實(shí)時(shí)信號(hào)支持排隊(duì),同樣不會(huì)丟失。對(duì)于目前 linux 的兩個(gè)信號(hào)安裝函數(shù):signal()及 sigaction()來說,它們都不能把 SIGRTMIN 以前的信號(hào)變成可靠信號(hào)(都不支持排隊(duì),仍有可能丟失,仍然是不可靠信號(hào)),而且對(duì) SIGRTMIN 以后的信號(hào)都支持排隊(duì)。這兩個(gè)函數(shù)的最大區(qū)別在于,經(jīng)過 sigaction 安裝的信號(hào)都能傳遞信息給信號(hào)處理函數(shù)(對(duì)所有信號(hào)這一點(diǎn)都成立),而經(jīng)過 signal 安裝的信號(hào)卻不能向信號(hào)處理函數(shù)傳遞信息。對(duì)于信號(hào)發(fā)送函數(shù)來說也是一樣的。實(shí)時(shí)信號(hào)與非實(shí)時(shí)信號(hào)早期Unix系統(tǒng)只定義了32種信號(hào), Rethat7.2支持64種信號(hào), 編號(hào)0-63(SIGRTMIN=31
溫馨提示
- 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. 人人文庫(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年電梯安裝維修工(八十一級(jí))考試試卷:電梯維修職業(yè)競(jìng)爭(zhēng)力分析
- 2025年德語DSH考試全真模擬試卷:寫作實(shí)戰(zhàn)與點(diǎn)評(píng)分析
- 2025年理財(cái)規(guī)劃師(金融分析師級(jí))考試試卷:財(cái)務(wù)報(bào)表分析實(shí)戰(zhàn)解析與技巧精講
- 輻射防護(hù)管理試題
- 免疫治療在自身免疫性皮膚病中的新型藥物研發(fā)動(dòng)態(tài)
- 2025年黃斑病診療試題
- 2025年軋鋼導(dǎo)衛(wèi)裝置項(xiàng)目提案報(bào)告模板
- 工業(yè)領(lǐng)域CCS技術(shù)應(yīng)用案例投資風(fēng)險(xiǎn)與收益評(píng)估
- 數(shù)字貨幣與貨幣政策傳導(dǎo):2025年新機(jī)制與新策略研究
- 廢石處理方案
- 信創(chuàng)的基礎(chǔ)知識(shí)培訓(xùn)課件
- 化學(xué)品作業(yè)場(chǎng)所安全警示標(biāo)志大全
- 2024科技住宅設(shè)計(jì)標(biāo)準(zhǔn)
- AQ/T 2061-2018 金屬非金屬地下礦山防治水安全技術(shù)規(guī)范(正式版)
- 鑄件廠安全現(xiàn)狀評(píng)價(jià)報(bào)告
- 翻譯中國(guó)智慧樹知到期末考試答案章節(jié)答案2024年湖南工業(yè)大學(xué)
- 綜合管廊及道路實(shí)施性施工組織設(shè)計(jì)概述
- 中國(guó)民族鋼琴藝術(shù)鑒賞智慧樹知到期末考試答案章節(jié)答案2024年西安交通大學(xué)
- 新編旅游職業(yè)道德 課件 譚為躍 第6、7章 旅游交通從業(yè)者道德素養(yǎng)、旅游購(gòu)物店從業(yè)者道德素養(yǎng)
- 2024屆新疆維吾爾阿克蘇地區(qū)小升初語文檢測(cè)卷含答案
評(píng)論
0/150
提交評(píng)論