




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、管道及有名管道在本系列序中作者概述了linux進(jìn)程間通信的幾種主要手段。其中管道和有名管道是最早的進(jìn)程間通信機(jī)制之一,管道可用于具有親緣關(guān)系進(jìn)程間的通信,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關(guān)系進(jìn)程間的通信。認(rèn)清管道和有名管道的讀寫規(guī)則是在程序中應(yīng)用它們的關(guān)鍵,本文在詳細(xì)討論了管道和有名管道的通信機(jī)制的基礎(chǔ)上,用實(shí)例對(duì)其讀寫規(guī)則進(jìn)行了程序驗(yàn)證,這樣做有利于增強(qiáng)讀者對(duì)讀寫規(guī)則的感性認(rèn)識(shí),同時(shí)也提供了應(yīng)用范例。1、管道概述及相關(guān)API應(yīng)用1.1 管道相關(guān)的關(guān)鍵概念管道是Linux支持的最初UnixIPC形式之一,具有以下特點(diǎn): 管道是半雙工的,數(shù)據(jù)只能向
2、一個(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ù)。1.2 管道的創(chuàng)建:#include<unistd.h>intpipe(intfd2)該函數(shù)創(chuàng)建的管道的兩端處于一個(gè)進(jìn)程中間,在實(shí)際應(yīng)用中沒有太大意義,因此,一個(gè)進(jìn)程
3、在由pipe()創(chuàng)建管道后,一般再fork一個(gè)子進(jìn)程,然后通過管道實(shí)現(xiàn)父子進(jìn)程間的通信(因此也不難推出,只要兩個(gè)進(jìn)程中存在親緣關(guān)系,這里的親緣關(guān)系指的是具有共同的祖先,都可以采用管道方式來進(jìn)行通信)。1.3 管道的讀寫規(guī)則:管道兩端可分別用描述字fd0以及fd1來描述,需要注意的是,管道的兩端是固定了任務(wù)的。即一端只能用于讀,由描述字fd0表示,稱其為管道讀端;另一端則只能用于寫,由描述字fd1來表示,稱其為管道寫端。如果試圖從管道寫端讀取數(shù)據(jù),或者向管道讀端寫入數(shù)據(jù)都將導(dǎo)致錯(cuò)誤發(fā)生。一般文件的I/O函數(shù)都可以用于管道,如close、read、write等等。從管道中讀取數(shù)據(jù):如果管道的寫端不
4、存在,則認(rèn)為已經(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_BUF在include/linux/limits.h中定義,不同的內(nèi)核版本可能會(huì)有所不同。Posix.1要求PIPE_BUF至少為512字節(jié),redhat7.2中為4096)。關(guān)于管道的讀規(guī)則驗(yàn)證:/*readtest.c*#include<unistd.h&
5、gt;#include<sys/types.h>#include<errno.h>main()(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)(.printf("pipecreateerrorn");return-1;)if(pid=fork()=0)(printf(&
6、quot;n");close(pipe_fd1);sleep(3);/一確保父進(jìn)程關(guān)閉寫端r_num=read(pipe_fd0,r_buf,100);printf("readnumis%dthedatareadfromthepipeis%dn",r_num,atoi(r_buf);close(pipe_fd0);exit();elseif(pid>0)close(pipe_fd0);/readstrcpy(w_buf,"111");if(write(pipe_fd1,w_buf,4)!=-1)printf("parentwri
7、teovern");close(pipe_fd1);/writeprintf("parentclosefd1overn");sleep(10);/* 程序輸出結(jié)果:* parentwriteover* parentclosefd1over* readnumis4thedatareadfromthepipeis111* 附加結(jié)論:* 管道寫端關(guān)閉后,寫入的數(shù)據(jù)將一直存在,直到讀出為止*I向管道中寫入數(shù)據(jù):向管道中寫入數(shù)據(jù)時(shí),linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進(jìn)程就會(huì)試圖向管道寫入數(shù)據(jù)。如果讀進(jìn)程不讀走管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將一直阻塞。
8、注:只有在管道的讀端存在時(shí),向管道中寫入數(shù)據(jù)才有意義。否則,向管道中寫入數(shù)據(jù)的進(jìn)程將收到內(nèi)核傳來的SIFPIPE信號(hào),應(yīng)用程序可以處理該信號(hào),也可以忽略(默認(rèn)動(dòng)作則是應(yīng)用程序終止)。對(duì)管道的寫規(guī)則的驗(yàn)證1:寫端對(duì)讀端存在的依賴性#include<unistd.h>#include<sys/types.h>main()intpipe_fd2;pid_tpid;charr_buf4;char*w_buf;intwritenum;intcmd;memset(r_buf,0,sizeof(r_buf);if(pipe(pipe_fd)<0)printf("pip
9、ecreateerrorn");return-1;if(pid=fork()=0)close(pipe_fd0);close(pipe_fd1);sleep(10);exit();elseif(pid>0)sleep(1);等待子進(jìn)程完成關(guān)閉讀端的操作close(pipe_fd0);/writew_buf="111"if(writenum=write(pipe_fd1,w_buf,4)=-1)printf("writetopipeerrorn");elseprintf("thebyteswritetopipeis%dn"
10、;,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)證#include<sys/types.h>#include<errno.h>main(inta
11、rgc,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)(printf("pipecreateerrorn");return-1;if(pid=fork()=0)(close(pipe_fd1);while(1)(sleep(1);rnum=read(pipe_fd0,r_buf,1000);printf("child:readnumis%dn”,r
12、num);close(pipe_fd0);exit();elseif(pid>0)(close(pipe_fd0);/writememset(r_buf,0,sizeof(r_buf);if(writenum=write(pipe_fd1,w_buf,1024)=-1)printf("writetopipeerrorn");elseprintf("thebyteswritetopipeis%dn",writenum);writenum=write(pipe_fd1,w_buf,4096);close(pipe_fd1);.輸出結(jié)果:注意,此行輸出說
13、明了寫入的非原子性注意,此行輸出說明了寫入的非原子性thebyteswritetopipe1000thebyteswritetopipe1000/thebyteswritetopipe1000thebyteswritetopipe1000thebyteswritetopipe1000thebyteswritetopipe120/thebyteswritetopipe0thebyteswritetopipe0結(jié)論:寫入數(shù)目小于4096時(shí)寫入是非原子的!如果把父進(jìn)程中的兩次寫入字節(jié)數(shù)都改為5000,則很容易得出下面結(jié)論:寫入管道的數(shù)據(jù)量大于4096字節(jié)時(shí),緩沖區(qū)的空閑空間將被寫入數(shù)據(jù)(補(bǔ)齊),直到
14、寫完所有數(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é)果見附一。$kill-l|grepSIGRTMIN運(yùn)行結(jié)果如下:30)SIGPWR31)SIGSYS32)SIGRTMIN33)SIGRTMIN+134)SIGRTMIN+235)SIGRTMIN+336)SIGRTMIN+437)SIG
15、RTMIN+538)SIGRTMIN+639)SIGRTMIN+740)SIGRTMIN+841)SIGRTMIN+942)SIGRTMIN+1043)SIGRTMIN+1144)SIGRTMIN+1245)SIGRTMIN+1346)SIGRTMIN+1447)SIGRTMIN+1548)SIGRTMAX-1549)SIGRTMAX-14實(shí)例二:用于具有親緣關(guān)系的進(jìn)程間通信下面例子給出了管道的具體應(yīng)用,父進(jìn)程通過管道發(fā)送一些命令給子進(jìn)程,子進(jìn)程解析命令,并根據(jù)命令作相應(yīng)處理。#include<sys/types.h>main()(intpipe_fd2;pid_tpid;char
16、r_buf4;char*w_buf256;intchildexit=0;inti;intcmd;memset(r_buf,0,sizeof(r_buf);if(pipe(pipe_fd)<0)(printf("pipecreateerrorn");return-1;if(pid=fork()=0)/子進(jìn)程:解析從管道中獲取的命令,并作相應(yīng)的處理(printf("n");close(pipe_fd1);sleep(2);while(!childexit)(read(pipe_fd0,r_buf,4);cmd=atoi(r_buf);if(cmd=0)
17、(printf("child:receivecommandfromparentovernnowchildprocessexitn");childexit=1;elseif(handle_cmd(cmd)!=0)return;sleep(1);close(pipe_fd0);exit();elseif(pid>0)/parent:sendcommandstochild(close(pipe_fd0);w_buf0="003"w_buf1="005"w_buf2="777"w_buf3="000&quo
18、t;for(i=0;i<4;i+)write(pipe_fd1,w_bufi,4);close(pipe_fd1);./下面是子進(jìn)程的命令處理函數(shù)(特定于應(yīng)用):inthandle_cmd(intcmd)(.if(cmd<0)|(cmd>256)/supposechildonlysupport256commands(printf("child:invalidcommandn");return-1;printf("child:thecmdfromparentis%dn”,cmd);return0;1.5管道的局限性管道的主要局限性正體現(xiàn)在它的特點(diǎn)上
19、: 只支持單向數(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)用2.1 有名管道相關(guān)的關(guān)鍵概念管道應(yīng)用的一個(gè)重大限制是它沒有名字,因此,只能用于具有親緣關(guān)系的進(jìn)程間通信,在有名管道(namedpipe或FIFO)提出后,該限制得到了克服。FIFO不同于管道之處在于它提供一個(gè)路徑名與之關(guān)聯(lián),以FIFO的文件形式存在于文件系統(tǒng)中。這樣,即使與FIF
20、O的創(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()等文件定位操作。2.2 有名管道的創(chuàng)建#include<sys/types.h>#include<sys/stat.h>intmkfifo(constchar*pathname,mode_tmode)該函數(shù)的第一個(gè)參數(shù)是一
21、個(gè)普通的路徑名,也就是創(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等等。2.3 有名管道的打開規(guī)則有名管道比管道多了一個(gè)打開操作:open。FIFO的打開規(guī)則:如果當(dāng)前打開操作是為讀而打開FIFO時(shí),若已經(jīng)有相應(yīng)進(jìn)程為寫而打開該FIFO,則當(dāng)前打開操作將成功返回;否則,可能阻塞直到有相應(yīng)進(jìn)程為寫而
22、打開該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。2.4 有名管道的讀寫規(guī)則從FIFO中讀取數(shù)據(jù):約定:如果一個(gè)進(jìn)程為了從FIFO中讀取數(shù)據(jù)而阻塞打開FIFO,那么稱該進(jìn)程內(nèi)的讀操作為設(shè)置了阻塞標(biāo)志的讀操作。 如果有進(jìn)程寫打開FIFO,且當(dāng)前FIFO內(nèi)沒有數(shù)據(jù),則對(duì)于設(shè)置了阻塞標(biāo)志的讀
23、操作來說,將一直阻塞。對(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í),讀操作返回0)。 如果沒有進(jìn)程寫打開FIFO,則設(shè)置了阻塞標(biāo)志的讀
24、操作會(huì)阻塞。注:如果FIFO中有數(shù)據(jù),則設(shè)置了阻塞標(biāo)志的讀操作不會(huì)因?yàn)镕IFO中的字節(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_BUF時(shí),linux將保證寫入的原子性。如果此時(shí)管道空閑緩沖區(qū)不足以容納要寫入的字節(jié)數(shù),則進(jìn)入睡眠,直到當(dāng)緩沖區(qū)中能夠容納要寫入的字節(jié)數(shù)時(shí),才開始進(jìn)行一次性寫操作。 當(dāng)要寫入的數(shù)據(jù)量大于PIPE_BUF時(shí),linux將不再保證寫入的原子性。FIFO緩
25、沖區(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昔誤,提醒以后再寫;對(duì)FIFO讀寫規(guī)則的驗(yàn)證:下面提供了兩個(gè)對(duì)FIFO的讀寫程序,適當(dāng)調(diào)節(jié)程序中的很少地方或者程序的命令行參數(shù)就可以對(duì)各種FIFO讀寫規(guī)
26、則進(jìn)行驗(yàn)證。程序1:寫FIFO的程序#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#defineFIFO_SERVER"/tmp/fifoserver"main(intargc,char*argv)/參數(shù)為即將寫入的字節(jié)數(shù)intfd;charw_buf4096*2;intreal_wnum;memset(w_buf,0,4096*2);if(mKfo(FIFO_SERVER,O_CREAT|O_EXCL)<0)&
27、;&(errno!=EEXIST)printf("cannotcreatefifoservern");if(fd=-1)if(errno=ENXIO)printf("openerror;noreadingprocessn");fd=open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);/設(shè)置非阻塞百志/fd=open(FIFO_SERVER,O_WRONLY,0);/設(shè)置阻塞標(biāo)志real_wnum=write(fd,w_buf,2048);if(real_wnum=-1).if(errno=EAGAIN)printf(&
28、quot;writetofifoerror;trylatern");elseprintf("realwritenumis%dn”,real_wnum);real_wnum=write(fd,w_buf,5000);/5000用于測(cè)試寫入7節(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讀出
29、的字節(jié)數(shù)#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#defineFIFO_SERVER"/tmp/fifoserver"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,
30、sizeof(r_buf);fd=open(FIFO_SERVER,O_RDONLY|O_NONBLOCK,0);/fd=open(FIFO_SERVER,O_RDONLY,0);/在此處可以把讀程序編譯成兩個(gè)不同版本:阻塞版本及非阻塞版本if(fd=-1)printf("open%sforreaderrorn");exit();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("nodataavlaib
31、len");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ù)不大于PIPE_BUF版本:版本nbw 阻塞且請(qǐng)求寫的字節(jié)數(shù)大于PIPE_BUF版本:bwg 阻塞且請(qǐng)求寫的字節(jié)數(shù)不大于PIPE_BUF版本:版本bw下面將使用br、nbr、w代替相應(yīng)程序中的阻塞讀、非阻塞讀驗(yàn)證阻塞寫操作
32、:1 .當(dāng)請(qǐng)求寫入的數(shù)據(jù)量大于PIPE_BUF時(shí)的非原子性:onbr1000obwg2 .當(dāng)請(qǐng)求寫入的數(shù)據(jù)量不大于PIPE_BUF時(shí)的原子性:onbr1000obw驗(yàn)證非阻塞寫操作:1 .當(dāng)請(qǐng)求寫入的數(shù)據(jù)量大于PIPE_BUF時(shí)的非原子性:onbr1000onbwg2 .請(qǐng)求寫入的數(shù)據(jù)量不大于PIPE_BUF時(shí)的原子性:onbr1000onbw不管寫打開的阻塞標(biāo)志是否設(shè)置,在請(qǐng)求寫入的字節(jié)數(shù)大于4096時(shí),都不保證寫入的原子性。但二者有本質(zhì)區(qū)別:對(duì)于阻塞寫來說,寫操作在寫滿FIFO的空閑區(qū)域后,會(huì)一直等待,直到寫完所有數(shù)據(jù)為止,請(qǐng)求寫入的數(shù)據(jù)最終都會(huì)寫入FIFO;而非阻塞寫則在寫滿FIFO的空
33、閑區(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)程間通信,用戶自己創(chuàng)建管道,并完成讀寫操作。FIFO可以說是管道的推廣,克服了管道無名字的限制,使得無親緣關(guān)系的進(jìn)程同樣可以采用先進(jìn)先出的通信機(jī)制進(jìn)行通信。管道和FIFO的數(shù)據(jù)是字節(jié)流,應(yīng)用程序之間必須事先確定特定的傳輸"協(xié)議",采用傳播具
34、有特定意義的消息。要靈活應(yīng)用管道及FIFO,理解它們的讀寫規(guī)則是關(guān)鍵。附1:kill-l的運(yùn)行結(jié)果,顯示了當(dāng)前系統(tǒng)支持的所有信號(hào):1)SIGHUP5)SIGTRAP9)SIGKILL13)SIGPIPE18)SIGCONT22)SIGTTOU26)SIGVTALRM30)SIGPWR2)SIGINT6)SIGABRT10)SIGUSR114)SIGALRM19)SIGSTOP23)SIGURG27)SIGPROF31)SIGSYS3)SIGQUIT7)SIGBUS11)SIGSEGV15)SIGTERM20)SIGTSTP24)SIGXCPU28)SIGWINCH32)SIGRTMIN4)SI
35、GILL8)SIGFPE12)SIGUSR217)SIGCHLD21)SIGTTIN25)SIGXFSZ29)SIGIO33)SIGRTMIN+134)SIGRTMIN+235)SIGRTMIN+336)SIGRTMIN+437)SIGRTMIN+538)SIGRTMIN+639)SIGRTMIN+740)SIGRTMIN+841)SIGRTMIN+942)SIGRTMIN+1043)SIGRTMIN+1144)SIGRTMIN+1245)SIGRTMIN+1346)SIGRTMIN+1447)SIGRTMIN+1548)SIGRTMAX-1549)SIGRTMAX-1450)SIGRTMAX
36、-1351)SIGRTMAX-1252)SIGRTMAX-1153)SIGRTMAX-1054)SIGRTMAX-955)SIGRTMAX-856)SIGRTMAX-757)SIGRTMAX-658)SIGRTMAX-559)SIGRTMAX-460)SIGRTMAX-361)SIGRTMAX-262)SIGRTMAX-163)SIGRTMAX除了在此處用來說明管道應(yīng)用外,接下來的專題還要對(duì)這些信號(hào)分類討論。附2:對(duì)FIFO打開規(guī)則的驗(yàn)證(主要驗(yàn)證寫打開對(duì)讀打開的依賴性)#include<sys/types.h>#include<sys/stat.h>#include<errno.h>#include<fcntl.h>#defineFIFO_SERVER"/tmp/fifos
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 材料疲勞斷裂影響因素研究重點(diǎn)基礎(chǔ)知識(shí)點(diǎn)
- 食用油火災(zāi)應(yīng)急處置預(yù)案(3篇)
- 火災(zāi)應(yīng)急預(yù)案范文文庫(3篇)
- 動(dòng)態(tài)編程與遞歸解法試題及答案
- 網(wǎng)絡(luò)管理員職業(yè)素養(yǎng)提升及試題答案
- 企業(yè)品牌建設(shè)與戰(zhàn)略目標(biāo)試題及答案
- 編程語言趨勢(shì)及其對(duì)職業(yè)發(fā)展的影響試題及答案
- 2025年VB考試重要資料與試題及答案
- 網(wǎng)絡(luò)管理員職業(yè)要求與考試試題答案
- 2025年軟考增分技巧探討試題及答案
- 《陸上風(fēng)電場(chǎng)工程概算定額》(NB-T 31010-2019)
- 小學(xué)科學(xué)冀人版六年級(jí)下冊(cè)全冊(cè)同步練習(xí)含答案
- 郵政儲(chǔ)蓄銀行-客戶經(jīng)理(個(gè)人消費(fèi)貸款)-試題+答案
- 教學(xué)能力比賽-教學(xué)實(shí)施報(bào)告(汽車運(yùn)用與維修)1
- 青年筑夢(mèng)之旅創(chuàng)業(yè)計(jì)劃書
- 髂動(dòng)脈瘤破裂的護(hù)理課件
- 網(wǎng)絡(luò)設(shè)備的認(rèn)證與授權(quán)管理最佳實(shí)踐手冊(cè)
- 山東省棗莊市山亭區(qū)2022年部編版小升初語文試卷
- 自然辯證法概論試題及答案
- 設(shè)備安全操作培訓(xùn)
- 社會(huì)學(xué)知識(shí)競(jìng)賽(58道含答案)
評(píng)論
0/150
提交評(píng)論