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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

利用管道实现进程间通信

發布時間:2024/8/26 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用管道实现进程间通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

管道通信

匿名管道

創建匿名管道

int pipe(int pipefd[2]);
pipefd[0] : 表示讀管道
pipefd[1] : 表示寫管道
返回 0表示成功,非零表示創建失敗。

代碼事例

//匿名管道 int main() {int fds[2];int len;char buf[100]={};if(pipe(fds)==-1) //創建管道perror("pipe"),exit(1);while(fgets(buf,100,stdin)){ len = strlen(buf);if(write(fds[1],buf,len)==-1) //把內容寫進管道perror("write"),exit(1);memset(buf,0x00,sizeof(char)*100);if(read(fds[0],buf,len)==-1) //從管道里面讀取內容到數組中perror("read"),exit(1);if(write(1,buf,len)==-1) //把從管道里讀出的內容寫到標準輸出perror("write"),exit(1);} return 0; }

結果展示

日常運用事例
who | wc -l
這樣的事例我們經常用到,用管道連接命令會令你得心應手。

圖片解析

利用管道進行父子進程通信

圖片解析原理

代碼示例:

//父子進程通信 int main() {char buf[1024]="change world!\n";int fds[2];if(pipe(fds)==-1)perror("pipe"),exit(1);pid_t pid = fork(); //創建匿名管道if(pid==0){close(fds[0]); //關閉管道讀描述符if(write(fds[1],buf,1024)==-1) //寫進管道perror("write"),exit(1);close(fds[1]); exit(1);}else{memset(buf,0x00,1024);close(fds[1]); //關閉管道寫描述符if(read(fds[0],buf,1024)==-1) //從管道讀內容perror("read"),exit(1);if(write(1,buf,1024)==-1)perror("write"),exit(1);close(fds[0]);exit(1);}return 0; }

結果

詳細過程圖解

管道讀寫規則

當沒有數據可讀時

  • O_NONBLOCK disable:read調用阻塞,即進程暫停執行,.一直等到有數據來到為止。
  • O_NONBLOCK enable:read調用返回-1,errno值為EAGAIN。

當管道滿的時候

  • O_NONBLOCK disable: write調用阻塞,直到有進程讀.走數據
  • O_NONBLOCK enable:調用返回-1,errno值為EAGAIN
  • 如果所有管道寫端對應的文件描述符被關閉,則read返回0
  • 如果所有管道讀端對應的文件描述符被關閉,則write操作會產生信號SIGPIPE,進而可能導致write進程退出
  • 當要寫.入的數據量不.大于PIPE_BUF時,linux將保證寫.入的原.子性。
  • 當要寫.入的數據量.大于PIPE_BUF時,linux將不再保證寫.入的原.子性。

管道特點

  • 只能?用于具有共同祖先的進程(具有親緣關系的進程)之間進?行通信;通常,一個管道由一個進程創建,然后該進程調?用fork,此后?父、?子進程之間就可應?用該管道。
  • 管道提供流式服務
  • 一般?而?言,進程退出,管道釋放,所以管道的?生命周期隨進程
  • 一般?而?言,內核會對管道操作進?行同步與互斥管道是半雙?工的,數據只能向?一個?方向流動;需要雙?方通信時,需要建?立起兩個管道

    命名管道

    我們剛剛可以用匿名管道在父子進程之間通信,那如果是兩個不想光的進程之間該如何通信呢?

創建命名管道

在命令行可以直接創建mkfifo filename

也可以在程序內部創建,相關函數
int mkfifo(const char *pathname, mode_t mode);

代碼示例:

int main() {mkfifo("my.p",0644);return 0; }

無關進程之間通信代碼示例

從標準輸入讀入內容進管道

#include<string.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>int main() {mkfifo("my.p",0664);int outfd = open("my.p",O_WRONLY);if(outfd==-1)perror("open my.txt"),exit(1);char buf[1024]={};int n = 0;while(fgets(buf,1024,stdin)){ write(outfd,buf,1024);memset(buf,0x00,1024);} close(outfd);

從管道中讀內容,標準輸出輸出

#include<string.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>int main() {int infd = open("my.p",O_RDONLY);if(infd==-1)perror("open my.p"),exit(1);char buf[1024]={};int n = 0;while((n = read(infd,buf,1024))>0){write(1,buf,n);memset(buf,0x00,1024);}close(infd); unlink("my.p"); //刪除管道return 0; }

運行結果:

這里就利用管道實現了兩個無關進程之間的通信。

匿名管道和命名管道的區別。

  • 匿名管道由pipe函數創建并打開。
  • 命名管道由mkfifo函數創建,打開?用open
  • FIFO(命名管道)與pipe(匿名管道)之間唯一的區別在它們創建與打開的?方式不同,一但這些工作完成之后,它們具有相同的語義。

轉載于:https://www.cnblogs.com/zhonglongbo/p/8976730.html

總結

以上是生活随笔為你收集整理的利用管道实现进程间通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。