最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

匿名管道

kubectl get pod -A | grep mysql

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

1. 管道|的基本行為

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

示例 1(stdout 被管道傳遞)

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

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

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

輸出:

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

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

2. 為什么|不處理 stderr

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

3. 原理

int pipe(int fd[2])

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

在這里插入圖片描述

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

管道只能一端寫(xiě)入,另一端讀出,所以上面這種模式容易造成混亂,因?yàn)楦高M(jìn)程和子進(jìn)程都可以同時(shí)寫(xiě)入,也都可以讀出。那么,為了避免這種情況,通常的做法是:

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

在這里插入圖片描述

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

請(qǐng)?zhí)砑訄D片描述

命名管道

簡(jiǎn)介

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

使用

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

創(chuàng)建 FIFO

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

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

FIFO 的特點(diǎn)

半雙工通信

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

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

阻塞機(jī)制

  • 如果沒(méi)有進(jìn)程在 ,寫(xiě)操作會(huì) 卡住,直到有進(jìn)程來(lái)讀。
  • 如果沒(méi)有進(jìn)程在 寫(xiě),讀操作會(huì) 卡住,直到有進(jìn)程來(lái)寫(xiě)。

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

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

如何使用 FIFO?

(1)命令行測(cè)試

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

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

終端1 會(huì)顯示 Hello FIFO

(2)C 語(yǔ)言示例

#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);  // 以寫(xiě)方式打開(kāi)
    write(fd, "Hello", 6);  // 寫(xiě)入數(shù)據(jù)
    close(fd);

    return 0;
}

常見(jiàn)問(wèn)題

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

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

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

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

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

  • mkfifo 會(huì)失敗,并提示 File exists。

原理

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

普通文件(如 a.txt):

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

命名管道(FIFO)

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

2. 命名管道的工作原理

(1)創(chuàng)建 FIFO

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

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

(2)進(jìn)程 A 寫(xiě)入數(shù)據(jù)

echo "Hello" > /tmp/myfifo
  • 進(jìn)程 A 打開(kāi) FIFO 以寫(xiě)方式O_WRONLY)。
  • 數(shù)據(jù) "Hello" 被寫(xiě)入內(nèi)核的 內(nèi)存緩沖區(qū)(不刷盤(pán)?。?。
  • 如果 沒(méi)有進(jìn)程在讀取,進(jìn)程 A 會(huì) 阻塞(卡?。?,直到有進(jìn)程來(lái)讀。

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

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

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

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

每個(gè)進(jìn)程打開(kāi) FIFO 時(shí),內(nèi)核會(huì) 復(fù)用同一個(gè) struct file(通過(guò)引用計(jì)數(shù) ref 管理)。

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

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

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

(3)半雙工通信

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

4. 類(lèi)比理解

把 FIFO 想象成 一條水管

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

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

特性

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

總結(jié)

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

簡(jiǎn)單來(lái)說(shuō):

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

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

相關(guān)文章

  • ubuntu運(yùn)行g(shù)cfsd-admin守護(hù)進(jìn)程需要認(rèn)證的解決方案

    ubuntu運(yùn)行g(shù)cfsd-admin守護(hù)進(jìn)程需要認(rèn)證的解決方案

    在Ubuntu中運(yùn)行`gcfsd-admin`守護(hù)進(jìn)程時(shí),如果每次進(jìn)入都需要輸入密碼,可以通過(guò)重新掛載`/data`磁盤(pán)來(lái)解決這個(gè)問(wèn)題,總結(jié)來(lái)說(shuō),需要對(duì)磁盤(pán)進(jìn)行重新掛載以消除鎖子
    2026-01-01
  • apache下運(yùn)行cgi模式的配置方法

    apache下運(yùn)行cgi模式的配置方法

    這篇文章主要介紹了apache下運(yùn)行cgi模式的配置方法,需要的朋友可以參考下
    2014-04-04
  • apache負(fù)載均衡的安裝和實(shí)現(xiàn)方法

    apache負(fù)載均衡的安裝和實(shí)現(xiàn)方法

    在負(fù)載均衡技術(shù)中,硬件設(shè)備是比較昂貴的,對(duì)于負(fù)載均衡的學(xué)習(xí)者如果不是在企業(yè)中應(yīng)用或者是學(xué)員中學(xué)習(xí),很少有機(jī)會(huì)能碰到實(shí)際操作的訓(xùn)練。所以,很多朋友都會(huì)選擇軟件方面的設(shè)置進(jìn)行研究。現(xiàn)在我們就來(lái)介紹一下再Apache下的Tomcat負(fù)載均衡的一些使用問(wèn)題
    2012-10-10
  • Node.js環(huán)境在linux上的部署教程

    Node.js環(huán)境在linux上的部署教程

    這篇文章主要介紹了Node.js環(huán)境在linux上的部署教程,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • Linux中出現(xiàn)“No space left on device”錯(cuò)誤的排查與解決方法

    Linux中出現(xiàn)“No space left on device”錯(cuò)誤的排查與解決方法

    這篇文章主要給大家介紹了關(guān)于在Linux中出現(xiàn)"No space left on device"錯(cuò)誤的排查與解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-09-09
  • Linux(Ubuntu) adb 無(wú)法識(shí)別的問(wèn)題解決方法

    Linux(Ubuntu) adb 無(wú)法識(shí)別的問(wèn)題解決方法

    這篇文章主要介紹了Linux(Ubuntu) adb 無(wú)法識(shí)別的問(wèn)題解決方法的相關(guān)資料,需要的朋友可以參考下
    2016-11-11
  • Linux環(huán)境實(shí)現(xiàn)替換jar包中class文件

    Linux環(huán)境實(shí)現(xiàn)替換jar包中class文件

    文章介紹了如何通過(guò)替換class文件來(lái)避免重復(fù)打包的問(wèn)題,具體步驟包括查找目標(biāo)文件目錄、解壓目標(biāo)文件、替換已解壓文件、替換jar包文件等
    2025-11-11
  • 基于windowx的Hyper-v安裝CentOS系統(tǒng)

    基于windowx的Hyper-v安裝CentOS系統(tǒng)

    這篇文章主要介紹了基于windowx的Hyper-v安裝CentOS系統(tǒng) ,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • centos7.0安裝離線(xiàn)JDK1.8方法詳解

    centos7.0安裝離線(xiàn)JDK1.8方法詳解

    這篇文章主要介紹了centos7.0安裝離線(xiàn)JDK1.8方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • linux系列之常用運(yùn)維命令整理筆錄(小結(jié))

    linux系列之常用運(yùn)維命令整理筆錄(小結(jié))

    這篇文章主要介紹了linux系列之常用運(yùn)維命令整理筆錄(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01

最新評(píng)論

靖安县| 甘谷县| 高陵县| 杭州市| 巴林左旗| 青海省| 临猗县| 改则县| 巴塘县| 乡宁县| 延津县| 陆丰市| 黄浦区| 玉山县| 黔西县| 阿拉尔市| 玛曲县| 皋兰县| 托克托县| 洛浦县| 栖霞市| 虹口区| 平顺县| 邵武市| 昆山市| 河间市| 前郭尔| 太白县| 确山县| 湖口县| 蒙城县| 潜山县| 合江县| 阿城市| 津南区| 武汉市| 永顺县| 永顺县| 平谷区| 汪清县| 连江县|