進程通訊:管道

管道,通常指無名管道,是 UNIX 系統IPC最古老的形式。

1、特點:

  • 它是半雙工的(即數據只能在一個方向上流動),具有固定的讀端和寫端。
  • 它只能用于具有親緣關系的進程之間的通信(也是父子進程或者兄弟進程之間)。
  • 它可以看成是一種特殊的文件,對于它的讀寫也可以使用普通的read、write 等函數。但是它不是普通的文件,并不屬于其他任何文件系統,并且只存在于內存中。

1). 當一個管道建立時,它會創建兩個文件描述符:fd[0]為讀而打開,fd[1]為寫而打開。如下圖:?

要關閉管道只需將這兩個文件描述符關閉即可。

2). 單個進程中的管道幾乎沒有任何用處。所以,通常調用 pipe 的進程接著調用 fork,這樣就創建了父進程與子進程之間的 IPC 通道。如下圖所示:

?

1. 測試代碼:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{int pipefd[2];int ret, nwrite, nread;pid_t pid;char writebuf[1024];char readbuf[1024];ret = pipe(pipefd);if (ret == -1){perror("pipe");return -1;}pid = fork();if (pid == -1){perror("fork");return -1;}else if (pid == 0){close(pipefd[1]);while (1){nread = read(pipefd[0], readbuf, sizeof(readbuf));if (nread == -1){perror("read");exit(-1);}printf("read from pipe %s\n", readbuf);if (!strncmp(readbuf, "quit", 4))break;}}if (pid > 0){close(pipefd[0]);while (1){fgets(writebuf, sizeof(writebuf), stdin);nwrite = write(pipefd[1], writebuf, sizeof(writebuf));if (nwrite == -1){perror("write");exit(-1);}if (!strncmp(writebuf, "quit", 4))break;}}
}

輸出結果:

?

有名管道

1. 為何提出有名管道的說法,目的是為了克服無名管道的不足之處:

  • 無名管道只能是用于具有親緣關系的進程之間,這就限制了無名管道的使用范圍。
  • 有名管道可以使互不相關的兩個進程互相通信,有名管道可以通過路徑名來指出。并在文件系統課件為了這種有名管道,Linux中專門設立了一個專門的特殊文件系統-管道文件,以FIFO的形式存在于文件系統中,這樣,即使與FIFO的創建者不存在親緣關系的進程,只要訪問該路徑,就能彼此通過FIFO相互通信,因此,通過FIFO不相關的進程也能交換數據,但在磁盤只是一個節點,而文件的數據只存在內存緩沖頁面上,與普通管道一樣。

2. 有名管道的創建

有名管道可以從命令行上創建,命令行方法是使用下面這個命令:

$ mkfifo myfifo

有名管道也可以從程序里創建,相關API有:

int mkfifo(cosnt char *path, mode_t mode);

參數:

  • 第一個參數是一個普通的路徑名,也就是創建后FIFO名字。
  • 第二個參數與打開普通文件的open函數中的mode參數相同(文件的讀寫權限),如果mkfifo的一個參數是一個已經存在路徑名時,會返回EEXIST錯誤,所以一般典型的調用代碼會檢查是否返回該錯誤,如果確實返回該錯誤,那么要調用打開FIFO的函數open就可以了。

3. FIFO的open函數打開規則:
O_RDONLY、O_WRONLY和O_NONBLOCK標志共有四種合法的組成方式:

flags = O_RDONLY:open將會調用阻塞,除非有另外一個進程以寫的方式打開用一個FIFO,否則一直等待。
flags = O_WRONLY:open將會調用阻塞,除非有另外一個進程以讀的方式打開同一個FIFO,否則一直等待。
flags =?O_RDONLY | O_NONBLOCK:如果此時沒有其他進程以寫的方式打開FIFO,此時open也會成功返回,此時FIOF被讀打開,而不會返回錯誤。
flag是= O_WRONLY | O_NONBLOCK:立即返回,如果此時沒有其他進程以讀的方式打開,open會失敗打開,此時FIOF沒有被打開,返回-1。
?

?

?程序1:
?

// writefifo.c
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>int main(int argc, const char *argv[])
{int fd, nwrite;char buf[1024] = "\0";if (access(argv[1], F_OK) != 0){int ret = mkfifo(argv[1], 0666);if (ret == -1){perror("mkfifo");exit(-1);}}fd = open(argv[1], O_WRONLY);if (fd == -1){perror("open");return -1;}while (1){fgets(buf, sizeof(buf), stdin);buf[strlen(buf) - 1] = '\0';nwrite = write(fd, buf, strlen(buf));if (nwrite == -1){perror("write error");return -1;}if (!strncmp(buf, "quit", 4))break;}return 0;
}

程序2:

//readfifo.c
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, const char *argv[])
{int ret, fd, nread;char buf[1024] = "\0";if (access(argv[1], F_OK) != 0){ret = mkfifo(argv[1], 0666);if (ret == -1){perror("mkfifo");exit(-1);}}fd = open(argv[1], O_RDONLY);if (fd == -1){perror("open");exit(-1);}while (1){nread = read(fd, buf, sizeof(buf));if (nread == -1){perror("read errro");exit(-1);}printf("read from fifo is %s\n", buf);if (!strncmp(buf, "quit", 4))break;memset(buf, '\0', sizeof(buf));}return 0;
}

輸出結果:?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385656.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385656.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385656.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java基礎入門答案譚曉芳,原理+實戰講解

One&#xff1a;JVM實踐思維圖&#xff08;完整版&#xff09; Two&#xff1a; 走近Java 概述 Java技術體系Java發展史Java虛擬機家族&#xff1a;&#xff08;Sun Classic/Exact VM、HotSpot VM、Mobile/Embedded VM、BEA JRockit/IBM J9 VM、BEA Liquid VM/Azul VM、Apache…

Leetcode 102. 二叉樹的層次遍歷

給定一個二叉樹&#xff0c;返回其按層次遍歷的節點值。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 例如: 給定二叉樹: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其層次遍歷結果&#xff1a; [ [3], [9,20], [15,7…

java基礎常問面試題,面試必問

一、首先本職工作一定要做好做精 本人之前在干兼職的時候&#xff0c;也忽視過本職工作&#xff0c;從而導致自己落后平均技術水平&#xff0c;雖然之后迎頭趕上&#xff0c;但這不能不算是個遺憾。前在接一些活的時候就感覺技術的重要性了&#xff0c;如果當年我技術再好些&a…

Leetcode | 107. Binary Tree Level Order Traversal II

題目&#xff1a;二叉樹的層次遍歷 II 1. 代碼①&#xff1a;深度優先搜索(鏈接&#xff09; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NUL…

java基礎教程哪個好,吐血整理

RabbitMQ&#xff1a; 優點&#xff1a;輕量&#xff0c;迅捷&#xff0c;容易部署和使用&#xff0c;擁有靈活的路由配置 缺點&#xff1a;性能和吞吐量較差&#xff0c;不易進行二次開發 RocketMQ&#xff1a; 優點&#xff1a;性能好&#xff0c;穩定可靠&#xff0c;有活…

java基礎教程哪個好,面試必會

如何才可以進大廠&#xff1f; 答案其實也很簡單&#xff0c;能力學歷。不知道大家有沒有發現&#xff0c;大廠的一些部門對于學歷要求已經放低了&#xff0c;阿里的一些部門同樣也招大專學歷的程序員&#xff0c;當然肯定也是因為他的能力足夠出色。 對于準備秋招的你來說&a…

java基礎教程第三版耿祥義,后臺開發JAVA崗

Java虛擬機內存模型 Java虛擬機內存模型中定義的訪問操作與物理計算機處理的基本一致&#xff01; Java中通過多線程機制使得多個任務同時執行處理&#xff0c;所有的線程共享JVM內存區域main memory&#xff0c;而每個線程又單獨的有自己的工作內存&#xff0c;當線程與內存區…

501. 二叉搜索樹中的眾數

給定一個有相同值的二叉搜索樹&#xff08;BST&#xff09;&#xff0c;找出 BST 中的所有眾數&#xff08;出現頻率最高的元素&#xff09;。 假定 BST 有如下定義&#xff1a; 結點左子樹中所含結點的值小于等于當前結點的值結點右子樹中所含結點的值大于等于當前結點的值左…

java基礎案例教程黑馬程序員案例答案,真香

掌握核心知識 1、90%幾率面試被問&#xff0c;吃透原理&#xff0c;面試不慌&#xff08;Spring原理&#xff09; 2、大廠必問Redis&#xff0c;趕緊碼起來&#xff08;Redis核心原理&#xff09; 3、MySQL從入門到實戰都在這篇&#xff0c;面試笑談優化 當然核心知識不止這三…

java基礎的三個框架,進階學習資料!

阿里巴巴一面 自我介紹這個就不說了&#xff0c;開頭必問的說一下StringBuilder 和 StringBufferSpring bean加載&#xff0c;實例化的過程Spring AOP源碼看過嗎java內存模型說一下如果給你一個map&#xff0c;里面有很多很多對象&#xff0c;那么這個map存放在哪了解GC算法嗎…

實驗3 | 由遍歷序列構造二叉樹

二叉樹構造定理&#xff1a; 定理7.1&#xff1a;任何n&#xff08;n>0&#xff09;個不同結點的二又樹&#xff0c;都可由它的中序序列和先序序列唯一地確定。 定理7.2&#xff1a;任何n&#xff08;n&#xff1e;0&#xff09;個不同結點的二又樹&#xff0c;都可由它的…

萬字總結!java讓字符串反轉

Java基礎 JDK 和 JRE 有什么區別&#xff1f; 和 equals 的區別是什么&#xff1f;兩個對象的 hashCode()相同&#xff0c;則 equals()也一定為 true&#xff0c;對嗎&#xff1f;final 在 java 中有什么作用&#xff1f;java 中的 Math.round(-1.5) 等于多少&#xff1f;Stri…

String | 344. Reverse String

題目&#xff1a;反轉字符串 方法1&#xff1a; class Solution { public:string reverseString(string s) {int m (s.size() -1) / 2;for(int i 0; i < m; i){char c s[i];s[i] s[s.size() -1 - i];s[s.size() -1 - i] c;}return s; } }; 方法2&#xff1a;…

萬字總結!springcloud分布式限流

正文 作為后端開發&#xff0c;日常操作數據庫最常用的是寫操作和讀操作。讀操作我們下邊會講&#xff0c;這個分類里我們主要來看看寫操作時為什么會導致 SQL 變慢。 刷臟頁 臟頁的定義是這樣的&#xff1a;內存數據頁和磁盤數據頁不一致時&#xff0c;那么稱這個內存數據頁…

String | 263. Ugly Number

題目&#xff1a;丑數 方法1 class Solution { public:bool isUgly ( int num ) {if (num 0)return false;while (num % 5 0)num / 5;while (num % 3 0)num / 3;while (num % 2 0)num / 2;return num 1;} };

萬字長文!java讀取json文件數據給對象

Java基礎核心筆記總結 由于篇幅限制&#xff0c;我就只以截圖展示目錄內容以及部分筆記內容&#xff0c;獲取完整版王者級核心寶典只需要點擊點贊關注即可獲取領取方式&#xff01; 在這個部分我們總結了Java的基礎知識&#xff0c;涵蓋了&#xff1a;概述、開發環境、開發環境…

三年Java開發,java基礎常問面試題

一、首先本職工作一定要做好做精 本人之前在干兼職的時候&#xff0c;也忽視過本職工作&#xff0c;從而導致自己落后平均技術水平&#xff0c;雖然之后迎頭趕上&#xff0c;但這不能不算是個遺憾。前在接一些活的時候就感覺技術的重要性了&#xff0c;如果當年我技術再好些&a…

Array | 867. Transpose Matrix

題目&#xff1a;轉置矩陣 方法1&#xff1a; class Solution { public:vector<vector<int>> transpose(vector<vector<int>>& A) {vector<vector<int>> num(A[0].size(), vector<int>(A.size(), 0));for(int i 0; i < A.…

三年Java開發,尚學堂java馬士兵全套

基于 Servlet 容器的 Web MVC 身為 Java 開發者&#xff0c;對于 Spring 框架并不陌生。它起源于 2002 年、Rod Johnson 著作《Expert One-on-One J2EE Design and Development》中的 Interface 21 框架&#xff0c;到了 2004 年&#xff0c;推出 Spring 1.0&#xff0c;從 XM…

Array | 74. Search a 2D Matrix

題目&#xff1a;搜索二維矩陣 方法1&#xff1a; class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, int target) {if(!matrix.size())return false;if(!matrix[0].size())return false;for(int i 0; i < matrix[matrix.size() …