亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Linux之匿名管道和命名管道詳解

 更新時間:2025年07月04日 09:32:03   作者:愛吃芝麻湯圓  
這篇文章主要介紹了Linux之匿名管道和命名管道的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

匿名管道

kubectl get pod -A | grep mysql

上面命令行里的「|」豎線就是一個管道,在命令行(如 Linux Shell 或 Windows CMD/PowerShell)中,管道操作符 | 的作用是將 前一個命令的標(biāo)準(zhǔn)輸出(stdout) 傳遞給 后一個命令的標(biāo)準(zhǔn)輸入(stdin)。但它默認(rèn) 不會傳遞標(biāo)準(zhǔn)錯誤(stderr),這是它的核心行為特點。

1. 管道|的基本行為

command1 | command2
  • command1stdout → 作為 command2stdin。
  • command1stderr → 直接打印到終端,不會傳遞給 command2。

示例 1(stdout 被管道傳遞)

# ls 成功時,stdout(文件列表)會傳遞給 grep
ls /usr/bin | grep "python"

示例 2(stderr 未被管道傳遞)

# 如果目錄不存在,錯誤信息會直接顯示,不會傳遞給 grep
ls /nonexistent_dir | grep "error"

輸出:

ls: cannot access '/nonexistent_dir': No such file or directory

(錯誤信息直接顯示,grep 不會處理它)

2. 為什么|不處理 stderr

  • 設(shè)計初衷| 的職責(zé)是傳遞 正常輸出,錯誤信息通常需要直接反饋給用戶。
  • 分離數(shù)據(jù)流:stdout(正常輸出)和 stderr(錯誤信息)是獨立的流,| 默認(rèn)只操作 stdout。

3. 原理

int pipe(int fd[2])

這里表示創(chuàng)建一個匿名管道,并返回了兩個描述符,一個是管道的讀取端描述符,另一個是管道的寫入端描述符fd。注意,這個匿名管道是特殊的文件,只存在于內(nèi)存,不存于文件系統(tǒng)中。

在這里插入圖片描述

所謂的管道,就是內(nèi)核里面的一串緩存。從管道的一段寫入的數(shù)據(jù),實際上是緩存在內(nèi)核中的,另一端讀取,也就是從內(nèi)核中讀取這段數(shù)據(jù)。另外,管道傳輸?shù)臄?shù)據(jù)是無格式的流且大小受限。

管道只能一端寫入,另一端讀出,所以上面這種模式容易造成混亂,因為父進程和子進程都可以同時寫入,也都可以讀出。那么,為了避免這種情況,通常的做法是:

  • 父進程關(guān)閉讀取的 fd[o],只保留寫入的 fd[1];
  • 子進程關(guān)閉寫入的fd[1],只保留讀取的 fd[o];

在這里插入圖片描述

在shell 里面執(zhí)行 A | B 命令的時候,A 進程和 B 進程都是shell 創(chuàng)建出來的子進程,A 和 B 之間不存在父子關(guān)系,它倆的父進程都是 shell。

請?zhí)砑訄D片描述

命名管道

簡介

  • 匿名管道,它的通信范圍是存在父子關(guān)系的進程。因為管道沒有實體,也就是沒有管道文件,只能通過fork來復(fù)制父進程 fd文件描述符,來達到通信的目的。
  • 對于命名管道,它可以在不相關(guān)的進程間也能相互通信。因為命令管道,提前創(chuàng)建了一個類型為管道的設(shè)備文件,在進程里只要使用這個設(shè)備文件,就可以相互通信。
  • 不管是匿名管道還是命名管道,進程寫入的數(shù)據(jù)都是緩存在內(nèi)核中,另一個進程讀取數(shù)據(jù)時候自然也是從內(nèi)核中獲取,同時通信數(shù)據(jù)都遵循先進先出原則,不支持Iseek之類的文件定位操作。

使用

int mkfifo(const char *pathname, mode_t mode);

創(chuàng)建 FIFO

使用 mkfifo 命令或 mkfifo() 函數(shù)創(chuàng)建:

mkfifo /tmp/myfifo  # 創(chuàng)建一個名為 /tmp/myfifo 的 FIFO
  • pathname:FIFO 的文件路徑(如 /tmp/myfifo)。
  • mode:權(quán)限(如 0644,表示用戶可讀寫,其他人只讀)。

FIFO 的特點

半雙工通信

  • 同一時間只能 ,不能同時讀寫(類似單行道)。
  • 示例:
# 終端1:寫入數(shù)據(jù)
echo "Hello" > /tmp/myfifo

# 終端2:讀取數(shù)據(jù)
cat /tmp/myfifo  # 輸出 "Hello"

阻塞機制

  • 如果沒有進程在 ,寫操作會 卡住,直到有進程來讀。
  • 如果沒有進程在 ,讀操作會 卡住,直到有進程來寫。

數(shù)據(jù)是流式的

  • 數(shù)據(jù)像水流一樣,讀完后會消失,不能像普通文件那樣隨意跳轉(zhuǎn)(lseek 無效)。

如何使用 FIFO?

(1)命令行測試

# 終端1:監(jiān)聽 FIFO(讀)
cat /tmp/myfifo

# 終端2:發(fā)送數(shù)據(jù)(寫)
echo "Hello FIFO" > /tmp/myfifo

終端1 會顯示 Hello FIFO。

(2)C 語言示例

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>

int main() {
    mkfifo("/tmp/myfifo", 0644);  // 創(chuàng)建 FIFO

    int fd = open("/tmp/myfifo", O_WRONLY);  // 以寫方式打開
    write(fd, "Hello", 6);  // 寫入數(shù)據(jù)
    close(fd);

    return 0;
}

常見問題

Q1: FIFO 和普通文件有什么區(qū)別?

  • FIFO 是 內(nèi)存中的管道,數(shù)據(jù)讀完就沒了;普通文件會持久化存儲。

Q2: FIFO 和匿名管道(|)有什么區(qū)別?

  • 匿名管道只能用于 父子進程,F(xiàn)IFO 可用于 任意進程。

Q3: 如果 FIFO 已經(jīng)存在,再創(chuàng)建會怎樣?

  • mkfifo 會失敗,并提示 File exists。

原理

1. 普通文件 vs. 命名管道(FIFO)

普通文件(如 a.txt):

  • 數(shù)據(jù)存儲在 磁盤 上,打開時會加載到內(nèi)存。
  • 修改后需要 寫回磁盤(刷盤)。
  • 多個進程打開同一文件時,數(shù)據(jù)可能不同步(除非加鎖)。

命名管道(FIFO)

  • 本質(zhì)是一個 內(nèi)存緩沖區(qū),只是偽裝成文件(磁盤上只有文件名,沒有實際數(shù)據(jù)塊)。
  • 數(shù)據(jù) 不寫入磁盤,直接在進程間流動。
  • 專為 進程間通信(IPC) 設(shè)計,速度快。

2. 命名管道的工作原理

(1)創(chuàng)建 FIFO

當(dāng)執(zhí)行 mkfifo /tmp/myfifo 時:

  1. 磁盤上創(chuàng)建一個 空文件(只有 inode,沒有數(shù)據(jù)塊)。
  2. 操作系統(tǒng)內(nèi)核維護一個 內(nèi)存緩沖區(qū)(用于存儲進程間傳遞的數(shù)據(jù))。

(2)進程 A 寫入數(shù)據(jù)

echo "Hello" > /tmp/myfifo
  • 進程 A 打開 FIFO 以寫方式O_WRONLY)。
  • 數(shù)據(jù) "Hello" 被寫入內(nèi)核的 內(nèi)存緩沖區(qū)(不刷盤?。?。
  • 如果 沒有進程在讀取,進程 A 會 阻塞(卡?。钡接羞M程來讀。

(3)進程 B 讀取數(shù)據(jù)

cat /tmp/myfifo
  • 進程 B 打開 FIFO 以讀方式O_RDONLY)。
  • 從內(nèi)核緩沖區(qū)讀取 "Hello",數(shù)據(jù)被消費(緩沖區(qū)清空)。
  • 如果 沒有進程在寫入,進程 B 會 阻塞,直到有進程寫入。

3. 關(guān)鍵點解析

(1)文件描述符與內(nèi)核結(jié)構(gòu)

每個進程打開 FIFO 時,內(nèi)核會 復(fù)用同一個 struct file(通過引用計數(shù) ref 管理)。

  • 第一次打開時創(chuàng)建 struct file,ref=1。
  • 第二個進程打開時,ref=2(指向同一個內(nèi)存緩沖區(qū))。
  • 關(guān)閉時 ref--,ref=0 時內(nèi)核才釋放資源。

(2)為什么數(shù)據(jù)不刷盤?

  • FIFO 的 設(shè)計目的 是進程間通信,數(shù)據(jù)不需要持久化。
  • 刷盤會 拖慢速度,且毫無意義(通信完數(shù)據(jù)即可丟棄)。

(3)半雙工通信

  • 同一時間只能 單向流動(讀或?qū)懀?/li>
  • 如果需要雙向通信,需創(chuàng)建 兩個 FIFO(一個負(fù)責(zé) A→B,一個負(fù)責(zé) B→A)。

4. 類比理解

把 FIFO 想象成 一條水管

寫入端:進程 A 往水管里倒水(數(shù)據(jù))。

讀取端:進程 B 從水管接水(數(shù)據(jù))。

特性

  • 水管沒有儲水功能(數(shù)據(jù)不持久化)。
  • 如果沒人接水,倒水的人會等待(阻塞寫入)。
  • 如果沒人倒水,接水的人會等待(阻塞讀?。?。

總結(jié)

特性命名管道(FIFO)普通文件
存儲位置內(nèi)存緩沖區(qū)磁盤
刷盤永不刷盤定期刷盤
多進程訪問共享同一緩沖區(qū)可能數(shù)據(jù)不同步
阻塞行為讀/寫會阻塞無阻塞
用途進程間通信數(shù)據(jù)存儲

簡單來說:

FIFO 是 披著文件外衣的內(nèi)存管道,讓進程可以通過文件路徑名通信,數(shù)據(jù) 不落盤,速度極快!

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • linux中如何添加用戶并賦予root權(quán)限詳解

    linux中如何添加用戶并賦予root權(quán)限詳解

    這篇文章主要先是給大家介紹了linux中如何添加用戶并賦予root權(quán)限,而后有詳細(xì)的介紹了Linux系統(tǒng)用戶組的管理,文中通過示例代碼介紹的很詳細(xì),相信對大家的理解和學(xué)習(xí)具有一定的參考借鑒價值,有需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • 在Linux環(huán)境下采用壓縮包方式安裝JDK 13的方法

    在Linux環(huán)境下采用壓縮包方式安裝JDK 13的方法

    JDK(Java Development Kit)是Sun公司(后被Oracle收購)推出的面向?qū)ο蟪绦蛟O(shè)計語言的開發(fā)工具包,擁有這個工具包之后我們就可以使用Java語言進行程序設(shè)計和開發(fā)。這篇文章主要介紹了在Linux環(huán)境下采用壓縮包方式安裝JDK 13,需要的朋友可以參考下
    2019-10-10
  • Linux有限狀態(tài)機FSM的理解與實現(xiàn)

    Linux有限狀態(tài)機FSM的理解與實現(xiàn)

    這篇文章主要幫助大家理解與實現(xiàn)Linux有限狀態(tài)機FSM,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Linux中的線程安全與線程同步詳解

    Linux中的線程安全與線程同步詳解

    這篇文章主要介紹了Linux中的線程安全與線程同步,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • crontab執(zhí)行時間與系統(tǒng)時間不一致問題解決

    crontab執(zhí)行時間與系統(tǒng)時間不一致問題解決

    這篇文章主要給大家介紹了關(guān)于crontab執(zhí)行時間與系統(tǒng)時間不一致問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • 在Linux系統(tǒng)中srv目錄的作用詳解

    在Linux系統(tǒng)中srv目錄的作用詳解

    在Linux系統(tǒng)中,/srv目錄用于存放與系統(tǒng)服務(wù)相關(guān)的數(shù)據(jù),如Web服務(wù)器、FTP服務(wù)器等,它提供了一種約定,用于將服務(wù)數(shù)據(jù)組織起來,便于管理和維護,通常,/srv目錄的內(nèi)容按照服務(wù)類型進行子目錄劃分,便于管理和備份
    2025-03-03
  • ubuntu20.04 LTS系統(tǒng)默認(rèn)源sources.list文件的修改

    ubuntu20.04 LTS系統(tǒng)默認(rèn)源sources.list文件的修改

    這篇文章主要介紹了ubuntu20.04 LTS系統(tǒng)默認(rèn)源sources.list文件的修改,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Linux系統(tǒng)設(shè)置開機自動運行腳本的方法實例

    Linux系統(tǒng)設(shè)置開機自動運行腳本的方法實例

    這篇文章主要給大家介紹了關(guān)于Linux系統(tǒng)設(shè)置開機自動運行腳本的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Linux系統(tǒng)具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 使用 Apache Web 服務(wù)器配置兩個或多個站點的方法

    使用 Apache Web 服務(wù)器配置兩個或多個站點的方法

    這篇文章主要介紹了使用 Apache Web 服務(wù)器配置多個站點的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-10-10
  • Linux安裝NodeJs并配合Nginx實現(xiàn)反向代理

    Linux安裝NodeJs并配合Nginx實現(xiàn)反向代理

    本篇文章主要介紹了Linux安裝NodeJs并配合Nginx實現(xiàn)反向代理,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-11-11

最新評論