日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux编程练习 --进程间通信1--无名管道

發(fā)布時間:2023/12/10 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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
  • /**************??
  • ??*?readtest.c?*??
  • ???
  • **************/???
  • #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);???????????//確保父進程關(guān)閉寫端???
  • ????????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);??
  • ????????//讀寫完成后,關(guān)閉管道??
  • ????????close(pipe1[READ]);??
  • ????????close(pipe2[WRITE]);??
  • ????????exit(0);??
  • ????}??
  • ????else?if(pid?>?0)?//父進程??
  • ????{??
  • ????????close(pipe2[WRITE]);??
  • ????????close(pipe1[READ]);??
  • ????????x?=?1;??
  • ????????//每次循環(huán)向管道1?的1?端寫入變量X?的值,并從??
  • ????????//管道2?的0?端讀一整數(shù)寫入X?再對X?加1,直到X?大于10??
  • ????????do{??
  • ????????????write(pipe1[WRITE],&x,sizeof(int));??
  • ????????????read(pipe2[READ],&x,sizeof(int));??
  • ????????????printf("parent?%d?read:?%d/n",getpid(),x++);??
  • ????????}while(x<=9);??
  • ????????//讀寫完成后,關(guān)閉管道??
  • ????????close(pipe1[WRITE]);??
  • ????????close(pipe2[READ]);??
  • ????????waitpid(pid,NULL,0);??
  • ????????exit(0);??
  • ????}??
  • }??
  • 總結(jié)

    以上是生活随笔為你收集整理的Linux编程练习 --进程间通信1--无名管道的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。