操作系統(tǒng)實驗,實驗7管道通信_第1頁
操作系統(tǒng)實驗,實驗7管道通信_第2頁
操作系統(tǒng)實驗,實驗7管道通信_第3頁
操作系統(tǒng)實驗,實驗7管道通信_第4頁
操作系統(tǒng)實驗,實驗7管道通信_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、實驗七 管道通信w實驗目的實驗目的加深對進程概念的理解,明確進程和程序的區(qū)別、進一步認識并發(fā)執(zhí)行的實質了解并熟悉Linux系統(tǒng)中利用管道實現(xiàn)進程通信的基本概念及方法熟悉Linux提供的有關系統(tǒng)調用函數(shù)/庫函數(shù),并能使用這些函數(shù)w實驗準備及預習實驗準備及預習閱讀講義附件8-管道通信,了解Linux系統(tǒng)中利用管道實現(xiàn)進程通信的基本概念及方法熟悉Linux提供的有關系統(tǒng)調用函數(shù)/庫函數(shù):pipe()、mkfifo、close()、read()、write()、lockf() w管道是Linux支持的最初Unix IPC形式之一,也是一種使用非常頻繁的通信機制w邏輯上被看作管道文件,只存在于內存中w管

2、道是單向的、先進先出的、無結構的、固定大小的字節(jié)流,把一個進程的標準輸出和另一個進程的標準輸入連接在一起w寫進程在管道的尾端寫入數(shù)據(jù),讀進程在管道的首端讀出數(shù)據(jù)w數(shù)據(jù)讀出后將從管道中移走,其它讀進程都不能再讀到這些數(shù)據(jù)w管道提供了簡單的流控制機制進程試圖讀空管道時,在有數(shù)據(jù)寫入管道前,進程將一直阻塞管道已經滿時,進程再試圖寫管道,在其它進程從管道中移走數(shù)據(jù)之前,寫進程將一直阻塞管道克服使用文件通信的兩個問題w限制管道的大小管道是一個固定大小的緩沖區(qū)Linux中,該緩沖區(qū)的大小為1頁,即4K字節(jié),因此不像文件那樣不加檢驗地增長寫管道時可能變滿,當這種情況發(fā)生時,隨后對管道的write()調用將默

3、認地被阻塞,等待某些數(shù)據(jù)被讀取,以便騰出足夠的空間供write()調用寫 w讀取進程可能工作得比寫進程快當所有當前進程數(shù)據(jù)已被讀取時,管道變空隨后的read()調用將默認地被阻塞,等待某些數(shù)據(jù)被寫入例例1:管道可用于輸入輸出重定向,它將一個命令的輸出直接定向到另一個命令的輸入。比如,當在某個shell程序(Bourneshell或C shell等)鍵入whowc -l后,相應shell程序將創(chuàng)建who以及wc兩個進程和這兩個進程間的管道??紤]下面的命令行:w$kill -l 顯示當前系統(tǒng)支持的所有信號w$kill -l | grep SIGRTMIN #include int pipe(int

4、 fd2)功能:創(chuàng)建一個管道,管道兩端可分別用描述字fd0以及fd1來描述注意管道的兩端是固定任務的,一端只能用于讀,由描述字fd0表示,稱為管道讀端;另一端則只能用于寫,由描述字fd1來表示,稱為管道寫端如果試圖從管道寫端讀取數(shù)據(jù),或者向管道讀端寫入數(shù)據(jù)都將導致錯誤發(fā)生一般文件的I/O函數(shù)都可以用于管道,如close、read、write等等管道的創(chuàng)建例例2:使用系統(tǒng)調用pipe()建立一條管道線,兩個子進程p1和p2分別向管道各寫一句話:child1 is sending a message!和child2 is sending a message!,父進程則從管道中讀出來自子進程的信息,

5、并顯示在屏幕上。 #include #include main()int fd2; int pid1,pid2;char OutPipe100, InPipe100;pipe(fd);while(pid1=fork()=-1);if(pid1=0)printf(“child process1 %dn”,getpid();lockf(fd1,1,0); /*加鎖鎖定寫入端*/sprintf(OutPipe, “child1 is sending a message!”);write(fd1, OutPipe, 50);/*將buf中的50個字符寫入管道*/sleep(5);/*睡眠5秒,暫時放棄

6、CPU*/lockf(fd1,0,0);/*解鎖釋放寫入端*/exit(0);/*結束進程pid1 */else/ else if pid1while(pid2=fork()=-1);if(pid2=0)printf(“child process2 %dn”,getpid()”);lockf(fd1,1,0);sprintf(OutPipe, “child2 is sending a message!”);write(fd1, OutPipe, 50);sleep(5);lockf(fd1,0,0);exit(0);else /*else if pid2*/printf(“parent pro

7、cess %dn”,getpid();wait(0);read(fd0,InPipe,50);printf(“%sn”,InPipe);wait(0);read(fd0,InPipe,50);printf(“%sn”,InPipe);exit(0);/*end if pid2*/*end if pid1*/w使用管道通信時,可關閉某些不需要的讀或寫描述符,建立起單向的讀或寫管道,然后用read和write像操作文件一樣去操作它:close(pipe_fd0);/*關閉讀管道*/ close(pipe_fd1);/*關閉寫管道*/發(fā)送進程利用文件系統(tǒng)的系統(tǒng)調用write( fd1, buf, s

8、ize),把buf中長度為size字節(jié)的字符消息送入管道入口(即寫入端)fd1接收進程則使用系統(tǒng)調用read( fd0, buf, size )從管道出口(即讀出端)fd0讀出size字節(jié)的字符消息放到buf中例例3:兩個進程,如子進程向父進程發(fā)送數(shù)據(jù),即使用子進程的fd1和父進程的fd0,同時關閉子進程的fd0和父進程的fd1#include #include #include #include #include #include int main() char *msg=I am child process!; /*子進程發(fā)送的數(shù)據(jù)*/ pid_t pid; char buf100;/*用

9、于讀取*/ int pi;/*創(chuàng)建管道時的返回值*/ int fd2;/*創(chuàng)建管道的參數(shù)*/ memset(buf,0,sizeof(buf);/*設置buf數(shù)組全為0,需*/ pi=pipe(fd); /*要引入#include*/ if(pi0) /*parent process*/ close(fd1); /*關閉寫管道*/ sleep(2);/*休眠一下等待數(shù)據(jù)寫入*/ if(read(fd0,buf,100)0)/*寫入管道*/ printf(Message from the pipe is:%sn,buf); close(fd0);/*關閉讀管道*/ waitpid(pid,NUL

10、L,0);/*待子進程退出*/ exit(0); else perror(fork() error!); exit(0); 管道的局限w主要局限性正體現(xiàn)在它的特點上只支持單向數(shù)據(jù)流只能用于具有親緣關系的進程之間沒有名字;管道的緩沖區(qū)是有限的所傳送的是無格式字節(jié)流管道的讀出方和寫入方必須事先約定好數(shù)據(jù)的格式,比如多少字節(jié)算作一個消息(或命令、或記錄)等等多少字節(jié)算作一個消息(命令、記錄)w普通管道只能用于一個進程家族之間的通信,如父子,兄弟之間w命名管道是有“名字”的管道,另外的進程可以看到并使用w普通管道在內存中,隨著進程的結束而消失,命名管道在磁盤上,作為一個特殊的設備文件而存在,進程結束不

11、消失w值得注意的是,管道嚴格遵循先進先出(first in first out),對管道及命名管道的讀總是從開始處返回數(shù)據(jù),對它們的寫則把數(shù)據(jù)添加到末尾有名管道有名管道的創(chuàng)建#include #include int mkfifo(const char * filmname, mode_t mode)w功能:創(chuàng)建一個名為filename的管道w參數(shù):mode模式設置管道的權限,如O_CREAT、O_EXCL、O_NONBLOCK等w返回:成功0,出錯返回-1 錯誤存儲在errno中有名管道的打開w有名管道比管道多了一個open操作 int open( const char * pathname

12、,int flags, mode_t mode);w返回:若所有核查的權限都通過了檢查則返回0,表示成功;只要有一個權限被禁止則返回-1指向打開文件的路徑打開文件的方式一般為0w參數(shù)flags 所能使用的旗標O_RDONLY ;O_WRONLY ;O_RDWR三種旗標互斥,但可與下列的旗標利用OR(|)組合 O_CREAT:文件不存在則自動建立文件 O_EXCL:與O_CREAT合用,檢查文件是否存在O_APPEND:所寫入的數(shù)據(jù)以附加方式加入到文件后 O_NONBLOCK:以不可阻塞的方式打開文件int fp=open(FIFO,O_RDWR|O_NONBLOCK,0);read(fp,bu

13、f,20);下面的實例演示了mkfifo的使用w請先以超級用戶身份登錄系統(tǒng),然后編輯/編譯源程序(兩個*.c程序),在圖形終端上執(zhí)行讀程序readfifo.c,讀程序執(zhí)行后將陷入循環(huán)w切換到字符終端1(ctrl+alt+f1),以超級用戶身份登錄并執(zhí)行寫程序writefifo.cw然后回到圖形終端,觀察讀程序的輸出變化#include #include #include #include #include #include #include #include #define FIFO /home/jkx/myfifo /*使用宏命名有名管道文件的路徑*/ /*readfifo.c*/ int

14、main() int fd; /*指向命名管道*/ char buf100;/*存儲數(shù)據(jù)*/ if(mkfifo(FIFO,O_CREAT|O_EXCL)0) /*創(chuàng)建管道*/ perror(Create error!n); unlink(FIFO);/*清除管道*/ exit(0); /* end if mkfifo*/ fd=open(FIFO,O_RDONLY|O_NONBLOCK,0);/*打開管道*/ if(fd0) /*讀取管道*/ printf(Get message:%sn,buf); else printf(Not accept any message!n); sleep(1);

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論