有名管道

一、有名管道

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

  • 無名管道只能是用于具有親緣關系的進程之間,這就限制了無名管道的使用范圍。
  • 有名管道可以使互不相關的兩個進程互相通信,有名管道可以通過路徑名來指出,并在文件系統課件

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

?

2. 有名管道的創建

  • 有名管道可以從命令行上創建,命令行方法是使用下面這個命令:
$ mkfifo myfifo
  • 有名管道也可以從程序里創建,相關API有:
#include <sys/stat/h>
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. 測試代碼:

#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{int ret = mkfifo("myfifo", 0666);if (ret == -1) {perror("mkfifo");exit(-1);}return 0;
}

輸出結果:


2. 測試代碼:

#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{if (access(argv[1], F_OK) != 0) {int ret = mkfifo(argv[1], 0666);if (ret == -1) {perror("mkfifo");exit(-1);}}return 0;
}

輸出結果:


3. 測試代碼:

程序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. 程序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;
}

?輸出結果:


【題目】驗證:flags =?O_RDONLY | O_NONBLOCK:如果此時沒有其他進程以的方式打開FIFO,此時open也會成功返回,此時FIOF被讀打開,而不會返回錯誤。

3. 測試代碼:

#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 | O_NONBLOCK);if (fd == -1) {perror("open");exit(-1);}printf("open read fifo successfully\n");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;
}

?輸出結果:

?


【題目】驗證:flag是= O_WRONLY | O_NONBLOCK:立即返回,如果此時沒有其他進程以讀的方式打開,open會失敗打開,此時FIOF沒有被打開,返回-1。

4. 測試代碼:

#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 | O_NONBLOCK);if (fd == -1) {perror("open");return -1;}printf("open write fifo successfully\n");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;
}

?輸出結果:

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

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

相關文章

Java進階:mysql的事務隔離級別面試題

一面&#xff1a; 阿里巴巴面試答案文末可以領取&#xff01; 1. 觸發新生代GC&#xff0c;如果存活對象總量大于survivor區容量&#xff0c;咋辦 2. 如果任務很多&#xff0c;線程池的阻塞隊列會撐爆內存的哪個區域 3. 棧在堆上嗎 4. GC root有哪些 5. 實例變量可以是GC…

有名管道(二)

一、從FIFO中讀取數據&#xff1a; 約定&#xff1a;如果一個進程為了從FIFO中讀取數據而以阻塞的方式打開FIFO&#xff0c;則稱內核為該進程的讀操作設置了阻塞標志。 如果有進程為寫而打開FIIF&#xff08;寫端存在&#xff09;&#xff0c;且當前FIFO內沒有數據&#xff0…

Java面試2021,java數據可視化項目

AOP簡介 AOP (Aspect Oriented Programing) 稱為&#xff1a;面向切面編程&#xff0c;它是一種編程思想。AOP 是 OOP&#xff08;面向對象編程 Object Oriented Programming)的思想延續 AOP采取橫向抽取機制&#xff0c;取代了傳統縱向繼承體系重復性代碼的編寫方式&#xff0…

gcc的使用

一、gcc編譯過程示意圖 分析&#xff1a; hello程序是一個高級&#xff23;語言程序&#xff0c;這種形式容易被人讀懂。為了在系統上運行hello.c程序&#xff0c;每條&#xff23;語句都必須轉化為低級機器指令。然后將這些指令打包成可執行目標文件格式&#xff0c;并以二進…

Java面試2021,java黑馬百度云

線程是否要鎖住同步資源 鎖住 悲觀鎖不鎖住 樂觀鎖 鎖住同步資源失敗 線程是否要阻塞 阻塞不阻塞自旋鎖&#xff0c;適應性自旋鎖 多個線程競爭同步資源的流程細節有沒有區別 不鎖住資源&#xff0c;多個線程只有一個能修改資源成功&#xff0c;其它線程會重試無鎖同一個線…

gdb使用

[sunbinlocalhost ~]$ gcc -Wall -g simple.c -o simple [sunbinlocalhost ~]$ ./simple Entering main ... result[1-100] 5050 result[1-10] 55 Exiting main ... [sunbinlocalhost ~]$ gdb simple 啟動gdb GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-110.el7 Copyrigh…

oppoJava面試題,java聲明全局變量的關鍵字

螞蟻一面 ??就做了?道算法題&#xff0c;要求兩?時內完成&#xff0c;給了?度為N的有重復元素的數組&#xff0c;要求輸出第10?的數。典型的TopK問題&#xff0c;快排算法搞定。算法題要注意的是合法性校驗、邊界條件以及異常的處理。另外&#xff0c;如果要寫測試?例&…

System V 消息隊列

一、System V 消息隊列 有一個隊列&#xff0c;隊列存放各種消息。每個進程可以把數據封存在消息中&#xff0c;再放入隊列。每個進程都可以拿到消息隊列&#xff0c;再從中取出/放入消息。 消息隊列也有管道一樣的不足&#xff0c;就是每個消息的最大長度是有上限的&#xf…

oppoJava面試題,java連接數據庫詳細步驟

美團一面&#xff08;50分鐘左右&#xff09; 進程和線程死鎖的必要條件網絡&#xff0c;七層協議TCP和UDP的區別hashmap 詳細講一下hashmap底層是如何解決hash沖突的hashmap和linkedhashmap數據庫的索引&#xff0c;為什么推薦自增id&#xff0c;有什么優點MySQL的引擎&#…

基本TCP套接字編程

1. socket函數原型&#xff1a; #include <sys/socket.h> int socket(int domain, int type, int protocol);2. bind函數原型&#xff1a; #include <sys/socket.h> int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);參數&#xff1a; ? st…

oppoJava面試題,騰訊社招三面多久聯系

梳理知識點&#xff0c;是快速提升技術的關鍵 前面講過&#xff0c;快速提升自己的技術硬實力其實是有方法的。大致就是梳理知識點夯實基礎進階深入學習實戰&#xff0c;下面我會一點點跟大家剖析&#xff0c;本文干貨滿滿&#xff0c;大家仔細閱讀。 ①梳理知識必備&#xff1…

oppoJava面試!傳智播客java基礎案例教程

零基礎如何學習Java&#xff1f; 首先&#xff0c;你要明白一點&#xff0c;Java入門不難&#xff01; 無論你是從事哪個行業&#xff0c;興趣一定是最好的老師&#xff0c;也是你學習的動力。 學習方式1&#xff1a;自學 自學模式其實我個人不建議絕大部分的人選擇&#x…

Redis高級項目實戰!北京java編程入門培訓

Dubbo面試專題 JVM面試專題 Java并發面試專題 Kafka面試專題 MongDB面試專題 MyBatis面試專題 MySQL面試專題 Netty面試專題 RabbitMQ面試專題 Redis面試專題 Spring Cloud面試專題 SpringBoot面試專題 zookeeper面試專題 最后 給大家送一個小福利 資料都是免費分享的&#xf…

poll函數

#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);參數&#xff1a; fds&#xff1a;監聽的文件描述符【數組】 struct pllfd {int fd; 待監聽的文件描述符short events; 待監聽的文件描述符對應的監聽事件short revents; 傳入時&…

Redis高級項目實戰,java配置jdk環境時

Spring Security觀后感——手繪思維腦(供參考) Spring Security手繪思維腦圖 手繪的思維導圖&#xff0c;是我自己根據自身的情況讀完這套阿里出品的Spring Security王者晉級文檔之后所繪的&#xff0c;相當于是一個知識的總結與梳理&#xff0c;我將其分為***“核心組件”與“…

select函數(一)

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 參數&#xff1a; nfds&#xff1a;監控的文件描述符集里最大文件描述符加1&#xff0c;因為此參數會告訴內核檢測前多少個文件文件描述符readfs&#xff1a;監控有讀…

Redis高級項目實戰,阿里P7級別面試經驗總結

第一次壓測 慘不忍睹&#xff0c;平均響應時間150ms&#xff0c;而且在這次壓測過程中還發現其它的問題&#xff0c;后臺報錯&#xff0c;經查是OpenSearch每秒查詢次數限制 優化代碼與配置 1、修改OpenSearch配置&#xff0c;并且將壓測環境中的OpenSearch連接地址改為內網地…

Makefile用法鏈接

Makefile的編寫及四個特殊符號的意義、$、$^、$ <font face"字體" size"字號" color"顏色">這里是需要突出顯示的內容</font> <font color#0099ff size12 face"黑體">黑體</font>

Redis高頻面試筆記:java版本號比較算法

1.三重心智模型 先給大家科普一個概念&#xff0c;“三重心智模型”。 認知科學家斯坦諾維奇&#xff0c;將人的心智模式&#xff0c;分成了三個部分。 第一層是自主心智&#xff0c;自主心智是我們通過進化與內隱學習獲得。比如&#xff0c;我們看到蛇就會害怕&#xff0c;情…

Redis高頻面試筆記:mysql8.0新特性

一、服務發布簡介 分布式系統架構下&#xff0c;服務發布是一件很麻煩的事情&#xff0c;特別是在構建自動發布流程和灰度測試的策略兩個核心方面。通常情況下如果不涉及數據層面的灰度流程&#xff0c;服務可以灰度上線&#xff0c;或者滾動上線&#xff0c;這兩種方式很常用…