Linux:管道文件及相關API

目錄

  • 前言
  • 一、管道文件
    • 1、基本概念
    • 2、匿名(無名)管道
    • 3、命名(有名)管道
    • 4、管道的特點
    • 5、思考:何時只能使用無名管道,何時又只能用有名管道?
      • 無名管道(匿名管道)適用的情況:
      • 有名管道(命名管道)適用的情況:
  • 二、相關API介紹
    • 1. `int pipe(int pipefd[2])`
    • 2. `int mkfifo(const char *pathname, mode_t mode)`
    • 3. `int open(const char *pathname, int flags)`
    • 4. `ssize_t read(int fd, void *buf, size_t count)`
    • 5. `ssize_t write(int fd, const void *buf, size_t count)`
    • 6、示例代碼
  • 四、參考閱讀

前言

??在 Linux 系統中,管道是一種非常常用的進程間通信機制,它簡單、高效,并且易于使用。本文將深入介紹 Linux 管道的原理、分類、特點以及使用方法,幫助讀者更好地理解和應用管道在系統編程中的重要性。

一、管道文件

1、基本概念

??在 Linux 中,管道文件(Pipeline)是一種特殊的文件類型,用于在進程之間進行通信。管道文件被用來將一個進程的標準輸出和另一個進程的標準輸入連接起來,實現這兩個進程之間的數據傳輸。管道文件有兩種類型:匿名管道命名管道

2、匿名(無名)管道

??匿名管道是最常見的一種管道,通過命令行中的豎線符號 | 創建。例如:command1 | command2,這樣可以將 command1 的輸出直接傳遞給 command2 的輸入。匿名管道只存在于相關進程的生命周期內,進程結束后管道也會自動關閉。

  • 特點:

    • 單向通信,數據從一個進程流向另一個進程。
    • 臨時性,只在相關進程生命周期內存在。
    • 通常用于連接兩個相關進程,例如 command1 | command2。
  • 使用注意事項:

    • 一次性的,一旦相關進程結束,管道就會關閉,數據會丟失。
    • 只能用于相關進程之間的通信,不能用于不相關進程之間的通信。

??在 Linux 中,可以使用一些常見的命令來演示匿名管道的使用,以實現進程之間的數據傳輸。以下是一個簡單的示例,使用 ls 命令列出當前目錄下的文件和子目錄,然后使用 grep 命令過濾出包含特定字符的結果。

ls | grep "txt"

??在這個示例中,ls 命令列出當前目錄下的文件和子目錄的信息,并將結果通過匿名管道傳遞給 grep 命令。grep 命令會過濾出包含 “txt” 字符串的結果,然后將結果輸出到標準輸出。這樣就實現了通過匿名管道連接兩個命令,實現數據傳輸和處理的功能。

??你可以嘗試在終端中執行上述命令,查看輸出結果。這種使用匿名管道的方式可以幫助簡化多個命令之間的數據傳遞和處理,提高系統管理和腳本編寫的效率。當然,除了 lsgrep,你還可以結合其他命令來展示匿名管道的強大功能和靈活性。

3、命名(有名)管道

??命名管道也稱為 FIFO(First In, First Out),它是一種特殊類型的文件,通過 mkfifo 命令創建。命名管道可以持久存在于文件系統中,并允許不相關的進程之間進行通信。命名管道通過文件系統中的路徑名進行訪問,進程可以像訪問普通文件一樣讀寫數據。

  • 特點:

    • 單向或雙向通信,可持久存在于文件系統中,多個進程之間進行通信。
    • 可用于不相關進程之間的通信。
    • 通過 mkfifo 命令創建。
  • 使用注意事項:

    • 需要注意文件權限和文件系統容量問題。
    • 小心處理管道阻塞的情況,避免死鎖問題。

創建命名管道的步驟如下:

  • 使用 mkfifo 命令創建命名管道文件:mkfifo pipe_file
  • 使用不同的進程分別打開該管道文件進行讀寫操作

??命名管道通常用于需要持久存在的進程通信,比如兩個獨立的進程之間需要進行數據交換,但又不需要建立像 TCP/IP 連接那樣的網絡通信。

4、管道的特點

  1. 單向通信: 管道是一種單向通信方式,數據從一個進程流向另一個進程。在匿名管道中,數據只能從管道的寫入端流向讀取端;在命名管道中,數據也是單向傳輸的,但可以支持雙向通信(半雙工)。

  2. 進程之間通信: 管道主要用于實現進程之間的通信,通過將一個進程的標準輸出重定向到管道,另一個進程的標準輸入重定向到同一管道,實現數據的傳遞。

  3. 數據流傳輸: 管道是一種數據流傳輸方式,數據以流的形式從一個進程傳輸到另一個進程,適合于需要連續處理數據的場景。

  4. 臨時性: 匿名管道是臨時的,只存在于相關進程的生命周期內(一般用于父子進程);而命名管道是持久的,可以在文件系統中保留,允許不相關的進程之間進行通信。

  5. 有限緩沖: 管道的數據傳輸有限制緩沖區大小,當緩沖區滿時,寫入端會被阻塞,直到讀端讀取數據,釋放緩沖區空間。

  6. 阻塞式通信: 當管道中沒有數據可讀時,讀取進程會被阻塞;當管道滿時,寫入進程也會被阻塞,直到有空間寫入數據。

  7. 操作簡便: 通過管道可以快速簡便地實現進程間的數據傳輸,無需繁瑣的網絡連接設置或文件讀寫操作。

  8. 常用于進程調用鏈: 管道經常用于構建進程調用鏈,將多個命令通過管道連接起來,實現復雜任務的處理。

??總的來說,管道是 Linux 系統中非常實用的進程間通信機制,具有簡單、高效、快速的特點,適用于一些需要實時數據傳輸并且不需要長期存儲的場景。通過合理地使用管道,可以有效提升進程之間的通信效率和數據處理能力。

5、思考:何時只能使用無名管道,何時又只能用有名管道?

無名管道(匿名管道)適用的情況:

  1. 用于父子進程通信: 無名管道通常用于在父子進程之間進行通信,因為無名管道是一種特殊的文件描述符,只能用于有親緣關系的進程之間通信。
  2. 單向通信: 無名管道是單向的,只能在一個方向上傳輸數據,通常用于實現單向數據傳輸的場景,比如父進程向子進程傳輸數據。
  3. 臨時傳輸數據: 無名管道通常被用作臨時通道,進程間傳輸少量數據,常用于將一個命令的輸出傳遞給另一個命令進行處理。

有名管道(命名管道)適用的情況:

  1. 用于任意進程間通信: 有名管道不僅可以用于有親緣關系的進程通信,還可以用于任意進程間通信,只要它們可以訪問同一個管道文件。
  2. 雙向通信: 有名管道支持雙向通信,進程可以通過同一個管道文件來實現雙向數據傳輸。
  3. 永久傳輸數據: 有名管道創建后會生成一個文件節點,直到被明確刪除前一直存在,因此適用于需要長期或者反復傳輸數據的場景。

綜上所述,無名管道適合用于父子進程之間的單向臨時通信,有名管道則適合用于任意進程之間的雙向永久通信。根據具體的需求和場景選擇合適的管道類型可以更有效地實現進程間的數據交換和通信。

二、相關API介紹

??在 Linux 系統中,管道文件相關的 API 主要包括 pipe()mkfifo()open()read()write() 等函數。以下是這些 API 的詳細解釋:

1. int pipe(int pipefd[2])

  • 功能: 創建一個匿名管道,并返回兩個文件描述符,pipefd[0] 用于讀取數據,pipefd[1] 用于寫入數據。
  • 參數: pipefd 是一個整型數組,用于存放管道的文件描述符。
  • 返回值: 若成功,返回 0;若失敗,返回 -1。
  • 示例:
    int fd[2];
    if (pipe(fd) == -1) {perror("pipe");exit(EXIT_FAILURE);
    }
    

2. int mkfifo(const char *pathname, mode_t mode)

  • 功能: 創建一個命名管道(FIFO)。
  • 參數:
    • pathname 是要創建的命名管道的路徑名。
    • mode 是文件的權限模式。
  • 返回值: 若成功,返回 0;若失敗,返回 -1。
  • 示例:
    if (mkfifo("/tmp/myfifo", 0666) == -1) {perror("mkfifo");exit(EXIT_FAILURE);
    }
    

3. int open(const char *pathname, int flags)

  • 功能: 打開一個管道文件,返回文件描述符。
  • 參數:
    • pathname 是要打開的管道文件的路徑名。
    • flags 指定打開文件的方式,如 O_RDONLY(只讀)和 O_WRONLY(只寫)。
  • 返回值: 若成功,返回一個新的文件描述符;若失敗,返回 -1。
  • 示例:
    int fd = open("/tmp/myfifo", O_WRONLY);
    if (fd == -1) {perror("open");exit(EXIT_FAILURE);
    }
    

4. ssize_t read(int fd, void *buf, size_t count)

  • 功能: 從管道文件中讀取數據。
  • 參數:
    • fd 是管道文件的文件描述符。
    • buf 是用于存放讀取數據的緩沖區。
    • count 是要讀取的字節數。
  • 返回值: 若成功,返回實際讀取的字節數;若到達文件末尾,返回 0;若失敗,返回 -1。
  • 示例:
    char buffer[100];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    

5. ssize_t write(int fd, const void *buf, size_t count)

  • 功能: 向管道文件中寫入數據。
  • 參數:
    • fd 是管道文件的文件描述符。
    • buf 是要寫入的數據。
    • count 是要寫入的字節數。
  • 返回值: 若成功,返回實際寫入的字節數;若失敗,返回 -1。
  • 示例:
    char *msg = "Hello, world!";
    ssize_t bytes_written = write(fd, msg, strlen(msg));
    

??以上是使用管道文件相關 API 的基本介綃,開發者在創建、打開、讀寫管道文件時可以結合這些函數來完成必要的操作。在實際編程過程中,需要注意處理錯誤情況,確保程序的穩定性和可靠性。

6、示例代碼

以下是一個簡單的示例代碼,展示如何在兩個進程之間使用管道文件進行通信。首先創建一個命名管道文件,然后通過 fork() 創建子進程,父進程向管道中寫入數據,子進程從管道中讀取數據,并打印輸出。具體代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>#define FIFO_PATH "/tmp/myfifo"int main() {// 創建命名管道文件if (mkfifo(FIFO_PATH, 0666) == -1) {perror("mkfifo");exit(EXIT_FAILURE);}pid_t pid = fork();if (pid == -1) {perror("fork");exit(EXIT_FAILURE);}if (pid > 0) {// 父進程寫入數據到管道int fd = open(FIFO_PATH, O_WRONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}char *msg = "Hello, child process!";if (write(fd, msg, strlen(msg)) == -1) {perror("write");exit(EXIT_FAILURE);}close(fd);} else if (pid == 0) {// 子進程從管道讀取數據int fd = open(FIFO_PATH, O_RDONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}char buffer[100];ssize_t bytes_read = read(fd, buffer, sizeof(buffer));if (bytes_read == -1) {perror("read");exit(EXIT_FAILURE);}buffer[bytes_read] = '\0';  // 添加字符串結束符printf("Child process received: %s\n", buffer);close(fd);}return 0;
}

??在此示例中,父進程向管道文件寫入字符串 “Hello, child process!”,子進程從管道文件讀取數據并打印輸出。這樣就實現了父子進程之間的簡單通信。在實際使用中,可以根據需求修改數據傳輸方式和內容,以滿足不同場景下的進程間通信需求。

四、參考閱讀

??初識linux之管道
??Linux——進程間通信——管道(文件)通信
??linux之《管道》

??歡迎大家指導和交流!如果我有任何錯誤或遺漏,請立即指正,我愿意學習改進。期待與大家一起進步!

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

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

相關文章

2024最新AI系統ChatGPT網站源碼, AI繪畫系統

一、前言說明 R5Ai創作系統是基于ChatGPT進行開發的Ai智能問答系統和Midjourney繪畫系統&#xff0c;支持OpenAI-GPT全模型國內AI全模型。本期針對源碼系統整體測試下來非常完美&#xff0c;那么如何搭建部署AI創作ChatGPT&#xff1f;小編這里寫一個詳細圖文教程吧。已支持GP…

CVE-2024-23334 AIOHTTP 目錄遍歷漏洞分析

漏洞描述&#xff1a; aiohttp 是一個用于 asyncio 和 Python 的異步 HTTP 客戶端/服務器框架。使用aiohttp作為Web服務器并配置靜態路由時&#xff0c;需要指定靜態文件的根路徑。此外&#xff0c;選項“follow_symlinks”可用于確定是否遵循靜態根目錄之外的符號鏈接。當“f…

css樣式元素的相對定位,絕對定位,固定定位等元素定位運用技巧詳解

文章目錄 1.相對定位 relative2.絕對定位 absolute3.固定定位4.display 轉換元素5.float浮動6.float產生內容塌陷問題7.overflow CSS樣式學習寶典&#xff0c;關注點贊加收藏&#xff0c;防止迷路哦 在CSS中關于定位的內容是&#xff1a;position:relative | absolute | static…

Unreal觸屏和鼠標控制旋轉沖突問題

Unreal觸屏和鼠標控制旋轉沖突問題 鼠標控制攝像機旋轉添加Input軸計算旋轉角度通過軸事件控制旋轉 問題和原因問題原因 解決辦法增加觸摸控制旋轉代碼觸屏操作下屏蔽鼠標軸響應事件 鼠標控制攝像機旋轉 通過Mouse X和Mouse Y控制攝像機旋轉。 添加Input軸 計算旋轉角度 通過…

SpringBootWeb快速入門

1.創建springboot工程&#xff0c;新建module 2.勾選web開發相關依賴 3.刪除多余文件 4.新建類 5.啟動類中運行main方法 6.啟動 默認端口號8080 7.打開瀏覽器&#xff0c;地址欄輸入 8.報錯 9.原因&#xff0c;控制層位置放錯&#xff0c;剪切controller層放進com.example …

[vue error] TypeError: Components is not a function

問題詳情 問題描述: element plus按需導入后&#xff0c;啟動項目報錯&#xff1a; 問題原因 unplugin-vue-components插件版本問題 查看 unplugin-vue-components插件可以發現版本太高了 問題解決 unplugin-vue-components 版本高了&#xff0c;我用的0.26.0&#xff0c…

AI寫的wordpress網站首頁模板 你覺得怎么樣?

以下是一個AI寫的基本的首頁模板示例&#xff0c;包含您提到的各個模塊。請注意&#xff0c;這只是一個基本框架&#xff0c;您可能需要根據您的具體需求進行進一步的定制和調整。 <!DOCTYPE html> <html <?php language_attributes(); ?>> <head>&…

【STM32+HAL】姿態傳感器陀螺儀MPU6050模塊

一、準備工作 有關OLED屏初始化的問題&#xff0c;詳見【STM32HAL】OLED顯示初始化配置 二、所用工具 1、芯片&#xff1a;STM32F10C8T6 2、CUBEMX配置軟件 3、 6 軸運動處理組件MPU6050 三、實現功能 OLED屏顯示姿態角 四、HAL配置步驟 1、開啟I2C1進行MPU6050通信 2、開…

供應鏈管理(SCM):界面設計全面掃盲,得供應鏈者得天下

大家伙&#xff0c;我是大千UI工場&#xff0c;專注UI分享和項目接單&#xff0c;本期帶來供應鏈系統的設計分享&#xff0c;歡迎大家關注、互動交流。 一、什么是SCM SCM系統是供應鏈管理&#xff08;Supply Chain Management&#xff09;系統的縮寫。供應鏈管理是指協調和管…

計算機視覺 了解OpenCV、COLMAP、PyTorch3D 和 OpenGL 中坐標系3D轉換的簡要指南

一、簡述 由于坐標系不同,在OpenCV、COLMAP、PyTorch3D和OpenGL等 3D 框架的世界中進行轉換可能會令人覺得頭疼。這里比較它們的坐標系并提供它們之間轉換的示例。核心還是找到在這些不同的 3D 環境中無縫工作所需的知識,讓我們以清晰直接的方式探索和理解這些坐標系。 2D 成…

【筆記版】edgecore.yaml分析總結

1. 文件路徑 /etc/kubeedge/config edgecore.yaml是該目錄下唯一的文件 附上鏈接&#xff1a;edgecore.yaml 2. 文件生成方式 2.1 方式一 使用keadm安裝部署的方式&#xff0c;執行完keadm join --cloudcore-ipportcloudcore監聽的IP地址:端口&#xff08;默認為10002&…

題目 1431: 藍橋杯第五屆真題-分糖果

題目描述: 有n個小朋友圍坐成一圈。老師給每個小朋友隨機發偶數個糖果&#xff0c;然后進行下面的游戲&#xff1a; 每個小朋友都把自己的糖果分一半給左手邊的孩子。 一輪分糖后&#xff0c;擁有奇數顆糖的孩子由老師補給1個糖果&#xff0c;從而變成偶數。 反復進行這個游戲…

設計模式精解:GoF 23種設計模式全解析

在軟件工程中&#xff0c;設計模式是為了解決常見的軟件設計問題而形成的一套經典解決方案。這些模式不僅能夠幫助開發者提高設計的靈活性和代碼的重用性&#xff0c;還能使問題的解決方案更加清晰、易于理解。《設計模式精解&#xff0d;GoF 23種設計模式》一書中所列舉的23種…

微信小程序的單位

在小程序開發中&#xff0c;rpx是一種相對長度單位&#xff0c;用于在不同設備上實現自適應布局。它是微信小程序特有的單位&#xff0c;表示屏幕寬度的 1/750。 rpx單位的好處在于可以根據設備的屏幕寬度進行自動換算&#xff0c;使得頁面在不同設備上保持一致的顯示效果。例…

學習筆記 前端

學習筆記 前端 學習記錄nodejsyarn解決方法 學習記錄 nodejs yarn 描述&#xff1a;想體驗一下chatgptnextweb在本地部署&#xff0c;但是本地部署需要yarn環境&#xff0c;網上看了yarn在node16以上就自帶了&#xff0c;而我的電腦是node18&#xff0c;所以就直接輸入了ya…

(十)SpringCloud系列——openfeign的高級特性實戰內容介紹

前言 本節內容主要介紹一下SpringCloud組件中微服務調用組件openfeign的一些高級特性的用法以及一些常用的開發配置&#xff0c;如openfeign的超時控制配置、openfeign的重試機制配置、openfeign集成高級的http客戶端、openfeign的請求與響應壓縮功能&#xff0c;以及如何開啟…

論文閱讀-高效構建檢查點

論文標題&#xff1a;On Efficient Constructions of Checkpoints 摘要 高效構建檢查點/快照是訓練和診斷深度學習模型的關鍵工具。在本文中&#xff0c;我們提出了一種適用于檢查點構建的有損壓縮方案&#xff08;稱為LC-Checkpoint&#xff09;。LC-Checkpoint同時最大化了…

MFC中CString的MakeUpper使用方法

在MFC中&#xff0c;CString類提供了MakeUpper函數來將字符串中的字符全部轉換為大寫。MakeUpper函數沒有參數&#xff0c;它會直接修改原始的CString對象。 下面是一些示例代碼&#xff0c;演示了如何使用MakeUpper函數&#xff1a; CString str "Hello, World!"…

uniapp開發android原生插件

一、下載原生開發SDK Android 離線SDK - 正式版 | uni小程序SDK (dcloud.net.cn)、 https://nativesupport.dcloud.net.cn/AppDocs/download/android.html 將開發uniappa原生android的插件解壓到ben本地目錄&#xff0c;目錄結構如下&#xff1a; 接下就可以使用 UniPlugin-Hel…

【本科組冠名獎】2023年第八屆數維杯數學建模挑戰賽獲獎感言

美國大學生數學建模競賽已結束過半&#xff0c;現在又迎來了2024年第九屆數維杯國賽&#xff0c;準備參加今年數維杯國賽的同學&#xff0c;今天我們一起看看去年優秀的選手都有什么獲獎感言吧~希望能幫到更多熱愛數學建模的同學。據說文末在看點贊的大佬都會直沖國獎呢&#x…