生活随笔
收集整理的這篇文章主要介紹了
Linux编程练习 --进程间通信1--无名管道
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
進程間通信系列--管道
管道可以說是最古老的IPC形式,所謂管道,是指進程間建立的一條通信的通道,從本質(zhì)上看,管道是UNIX文件概念的推廣管道通信的介質(zhì)是文件,先看一下管道的特點:
?
1.管道的特點:
? (1)管道是半雙工的,數(shù)據(jù)只能向一個方向流動;需要雙方通信時,需要建立起兩個管道;
? (2)無名管道只能用于父子進程或者兄弟進程之間(具有親緣關(guān)系的進程);后來發(fā)展了FIFO(也稱有名管道)
? (3)單獨構(gòu)成一種獨立的文件系統(tǒng):管道對于管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨構(gòu)成一種文件系統(tǒng),并且只存在與內(nèi)存中。
?? (4)數(shù)據(jù)的讀出和寫入:一個進程向管道中寫的內(nèi)容被管道另一端的進程讀出。寫入的內(nèi)容每次都添加在管道緩沖區(qū)的末尾,并且每次都是從緩沖區(qū)的頭部讀出數(shù)據(jù)。
?
2.無名管道API及操作:
頭文件:#include <unistd.h>
數(shù)據(jù)成員:int pipe_fd[2];
管道創(chuàng)建:int pipe(int fd[2])
??? 該函數(shù)創(chuàng)建的管道的兩端處于一個進程中間,在實際應(yīng)用中沒有太大意義,因此,一個進程在由pipe()創(chuàng)建管道后,一般再fork一個子進程,然后通過管道實現(xiàn)父子進程間的通信(因此也不難推出,只要兩個進程中存在親緣關(guān)系,這里的親緣關(guān)系指的是具有共同的祖先,都可以采用管道方式來進行通信)。
管道讀寫:
管道兩端可分別用描述字fd[0]以及fd[1]來描述,管道讀端:fd[0],管道寫端:fd[1];
讀管道規(guī)則:
?關(guān)閉管道的寫端:close (fd[WRITE]);
讀出:read(fd[READ],string,strlen(string));
讀出后關(guān)閉管道的讀端:close(fd[REAd]);
?
寫管道規(guī)則:
關(guān)閉管道的讀端:close(fd[REAd]);
寫入:write(fd[WRITE],string,strlen(string));
寫入后關(guān)閉管道的寫端:close (fd[WRITE]);
?
下面練習一個簡單的單管道通信:
父進程寫數(shù)據(jù),子進程負責讀出數(shù)據(jù)
?
[cpp]?view plaincopy
? ? ? ??? #include?<unistd.h>??? #include?<sys/types.h>??? #include?<errno.h>??? #define?????READ????0?? #define?????WRITE???1?? main()??? {????? ????int?pipe_fd[2];??????? ????pid_t?pid;???? ????char?r_buf[100];?????? ????char?w_buf[32];??????? ????char*?p_wbuf;??? ????int?r_num;???? ????int?cmd;?????? ????memset(r_buf,0,sizeof(r_buf));???? ????memset(w_buf,0,sizeof(r_buf));???? ????p_wbuf=w_buf;????? ????if(pipe(pipe_fd)<0)???????? ????{????????? ????????printf("pipe?create?error?");????????? ????????return?-1;???????? ????}??? ?????? ????if((pid=fork())==0)??? ????{????? ????????close(pipe_fd[WRITE]);???? ????????sleep(3);????????????? ????????r_num=read(pipe_fd[READ],r_buf,100);??? ????????printf(?"read?num?is?%d?the?data?read?from?the?pipe?is?%s?/n",r_num,r_buf);??????? ????????close(pipe_fd[READ]);????? ????????exit();??????????? ????}????? ????else?if(pid>0)????? ????{????????? ????????close(pipe_fd[READ]);????????? ????????strcpy(w_buf,"hello?world!/n");??????????? ????????if(write(pipe_fd[WRITE],w_buf,strlen(w_buf))==-1)????????? ????????????printf("parent?write?over/n?");??????????? ????????close(pipe_fd[WRITE]);???????? ????????printf("parent?close?fd[WRITE]?over?/n");????????? ????????sleep(10);??? ????}????? }???
編譯運行,看到預(yù)期結(jié)果
?
3.利用兩個管道進行雙向通信
(1)創(chuàng)建兩個管道:管道1(父->子),管道2(子->父)
(2)fork()產(chǎn)生子進程
(3)父進程:close(fd1[READ]); close(fd2[WRITE]);
(4)子進程:close(fd1[WRITE]); close(fd2[READ]);
下面做一個練習,是利用雙向通信實現(xiàn)父子進程協(xié)作把整數(shù)x從1加到10
[cpp]?view plaincopy
#include?<unistd.h>?? #include?<sys/stat.h>?? #include?<sys/types.h>?? #include?<stdio.h>?? #include?<fcntl.h>?? #define?MAXLINE?1024?? #define?READ????0?? #define?WRITE???1?? main(void)?? {?? ????int?x;?? ????pid_t?pid;?? ????int?pipe1[2],pipe2[2];?? ?????? ????pipe(pipe1);?? ????pipe(pipe2);?? ????pid?=?fork();?? ????if(pid?<?0)?? ????{?? ????????printf("create?process?error!/n");?? ????????exit(1);?? ????}?? ????if(pid?==?0)?????????? ????{?? ????????close(pipe1[WRITE]);?? ????????close(pipe2[READ]);?? ????????do?? ????????{?? ????????????read(pipe1[READ],&x,sizeof(int));?? ????????????printf("child?%d?read:?%d/n",getpid(),x++);?? ????????????write(pipe2[WRITE],&x,sizeof(int));?? ????????}while(x<=9);?? ?????????? ????????close(pipe1[READ]);?? ????????close(pipe2[WRITE]);?? ????????exit(0);?? ????}?? ????else?if(pid?>?0)??? ????{?? ????????close(pipe2[WRITE]);?? ????????close(pipe1[READ]);?? ????????x?=?1;?? ?????????? ?????????? ????????do{?? ????????????write(pipe1[WRITE],&x,sizeof(int));?? ????????????read(pipe2[READ],&x,sizeof(int));?? ????????????printf("parent?%d?read:?%d/n",getpid(),x++);?? ????????}while(x<=9);?? ?????????? ????????close(pipe1[WRITE]);?? ????????close(pipe2[READ]);?? ????????waitpid(pid,NULL,0);?? ????????exit(0);?? ????}?? }??
總結(jié)
以上是生活随笔為你收集整理的Linux编程练习 --进程间通信1--无名管道的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。