17 有名管道與無名管道之間的區別

2022-02-12 10:45:57 字數 4652 閱讀 3400

1)無名管道:

管道是半雙工的,資料只能向乙個方向流動;需要雙方通訊時,需要建立起兩個管道;只能用於父子程序或者兄弟程序之間(具有親緣關係的程序)。

單獨構成一種獨立的檔案系統:管道對於管道兩端的程序而言,就是乙個檔案,但它不是普通的檔案,它不屬於某種檔案系統,而是自立門戶,單獨構成一種檔案系統,並且只存在與記憶體中。

資料的讀出和寫入:乙個程序向管道中寫的內容被管道另一端的程序讀出。寫入的內容每次都新增在管道緩衝區的末尾,並且每次都是從緩衝區的頭部讀出資料。(有點像佇列哈)

#include

int pipe(int fd[2])

該函式建立的管道的兩端處於乙個程序中間,在實際應用中沒有太大意義,因此,乙個程序在由 pipe()

建立管道後,一般再

fork

乙個子程序,然後通過管道實現父子程序間的通訊(因此也不難推出,

只要兩個程序中存在親緣關係,這裡的親緣關係指的是具有共同的祖先,都可以採用管道方式來進行通訊

)。向管道中寫入資料時,linux

將不保證寫入的原子性,管道緩衝區一有空閒區域,寫程序就會試圖向管道寫入資料。如果讀程序不讀走管道緩衝區中的資料,那麼寫操作將一直阻塞。

注:只有在管道的讀端存在時,向管道中寫入資料才有意義。否則,向管道中寫入資料的程序將收到核心傳來的sifpipe

訊號,應用程式可以處理該訊號,也可以忽略(預設動作則是應用程式終止)。

2)有名管道:不同於管道之處在於它提供乙個路徑名與之關聯,以

fifo

的檔案形式存在於檔案系統中。

這樣,即使與fifo

的建立程序不存在親緣關係的程序,只要可以訪問該路徑,就能夠彼此通過

fifo

相互通訊(能夠訪問該路徑的程序以及

fifo

的建立程序之間),因此,通過

fifo

不相關的程序也能交換資料。

值得注意的是,fifo

嚴格遵循先進先出(

first in first out

),對管道及

fifo

的讀總是從開始處返回資料,對它們的寫則把資料新增到末尾。它們不支援諸如

lseek()

等檔案定位操作。

有名管道的建立

#include

#include

int mkfifo(const char * pathname, mode_t mode)

該函式的第乙個引數是乙個普通的路徑名,也就是建立後fifo

的名字。第二個引數與開啟普通檔案的

open()

函式中的

mode

引數相同。如果

mkfifo

的第乙個引數是乙個已經存在的路徑名時,會返回

eexist

錯誤,所以一般典型的呼叫**首先會檢查是否返回該錯誤,如果確實返回該錯誤,那麼只要呼叫開啟

fifo

的函式就可以了。一般檔案的

i/o函式都可以用於

fifo

,如close

、read

、write

等等3)無名管道由乙個在基本檔案系統儲存裝置上的

inode

,乙個與其相連的記憶體

inode

,兩個開啟檔案控制塊(分別對應管道的資訊傳送端和資訊接收端)及其所屬程序的描述資訊來標識,在系統執行

pipe(p

)命令列之後生成。並在

p[0]

中返回管道的讀通道開啟檔案描述等,在

p[1]

中返回管道的寫信道開啟檔案描述符。

從結構上看,無名管道沒有檔案路徑名,不占用檔案目錄項,因此檔案目錄結構中的鍊錶不適用於這種檔案,它只是存在於開啟檔案結構中的乙個臨時檔案,隨其所依附的程序的生存而生存,當程序終止時,無名管道也隨之消亡。

送入管道的資訊一旦被讀程序取用就從管道中消失了,讀寫操作之間符合

先進先出的佇列原則。

管道檔案是程序間通訊的工具,為了盡量少的占用系統儲存資源,一

般系統均將其限制為最大長度為4096

(pipsiz

)位元組的小型檔案

。當欲寫入的訊息超過4096

位元組時,就產生了讀、寫程序之間的同步問題。首先寫操作查詢

pipe

檔案中當前指標的偏移量

f-offset

,然後從此位置開始盡量寫入資訊,當長度達到

4096

位元組時,系統控制寫程序進入睡眠狀態,一直等待讀程序取走全部資訊時,檔案長度指標置

0,寫程序才被喚醒繼續工作。

為防止多個程序同時讀寫乙個管道檔案而產生混亂,在管道檔案的inode

標誌字i-flay

項中設定了

ilock

標誌項,以設定軟體鎖的方式實現多程序間對管道檔案的互斥使用。

無名管道存在著如下兩個嚴重的缺點。

第一,無名管道只能用於連線具有共同祖先的程序。

第二,無名管道是依附程序而臨時存在的。所以後來推出了一種無名管道的變種-

有名管道,它常被稱為

fifo

。有名管道除繼承了無名管道的所有特性優點之外,還屏棄了無名管道的兩個缺點。

首先,fifo

是一種永久性的機構,它具有普通的

unix

系統檔名。在系統下可利用

mknod

命令建立永久的管道,除非刻意刪除它,否則它將一直保持在系統中。

其次,正是由於有名管道以「檔名」來標識,所以只要事先約定某一特定檔名,那樣所有知道該約定的服務程序,不論它們之間是否有親屬關係,都可以便利地利用管道進行通訊。

通過下面的命令可以建立乙個命名管道:

/etc/mknod pipe_name p 

其中「pipe_name

」是要建立的命名管道的名字,引數

p 必須出現在命名管道名字之後。 

命名管道檔案被建立後,一些程序就可以不斷地將資訊寫入命名管道檔案裡,而另一些程序也可以不斷地從命名管道檔案中讀取資訊。對命名管道檔案的讀寫操作是可以同時進行的。下面的例子顯示命名管道的工作過程。

程序a、b、

c中執行的程式只是一條簡單的

echo

命令,它們不斷地把資訊寫入到命名管道檔案

/tmp/pipe1

中。與此同時,程式中的「

read msg

」命令不斷地從命名管道檔案

/tmp/pipe1

中讀取這些資訊,從而實現這些程序間的資訊交換。 

程式執行時,首先建立命名管道檔案,此時程式處於等待狀態,直到a、b

、c程序中某乙個程序往命名管道中寫入資訊時,程式才繼續往下執行。使用

rm命令可以刪除命名管道檔案從而清除已設定的 命名管道。 

下面是乙個用於記錄考勤的例子: 

在主機上執行的程式/tmp/text

產生命名管道

/tmp/pipe1

,並不斷地從命名管道中讀取資訊送螢幕上顯示。 

/tmp/text程式:

if [ !

-p /tmp/pipe1 ]

then

/etc/mknode /tmp/pipe1 p

fi while :

do read msg

if [ 「

$msg" = 「

" ]

then

continue

else

echo 「$

msg"

fi done < /tmp/pipe1

在終端上執行的是雇員簽到程式/tmp/text1

。每個雇員在任何一台終端上鍵入自己的名字或**,程式

/tmp/text1

將把這個名字連同當時的簽到時間送入命名管道。

/tmp/text1程式:

tty=『

who am i | awk 『』』

while :

doecho 「

enter your name: \c" > /dev/

$tty

read name

today=『

date

』 echo 「$

name\t

$today"

done > /tmp/pipe1

當雇員從終端上輸入自己的姓名後,執行/tmp/text

程式的主機將顯示類似下面的結果: 

wang thu jan 28 09:29:26 btj 1999

he thu jan 28 09:29:26 btj 1999

cheng thu jan 28 09:30:26 btj 1999

zhang thu jan 28 09:31:26 btj 1999

named pipes(命名管道)管道具有很好的使用靈活性,表現在:

1) 既可用於本地,又可用於網路。

2) 可以通過它的名稱而被引用。

3) 支援多客戶機連線。

4) 支援雙向通訊。

5) 支援非同步重疊

i/o操作。

不過,當前只有windows nt,unix

支援服務端的命名管道技術

,win95/97/98

等不支援。

sql server

等資料庫就有

named pipes

的連線方式。

(資料**於網際網路)

無名管道和有名管道

無名管道 無名管道建立 int pipe int filedis 2 當乙個管道建立時,它會建立兩個檔案描述符 filedis 0 用於讀管道,filedis 1 用於寫管道 管道用於不同程序間通訊。通常先建立乙個管道,再通過fork函式建立乙個子程序,該子程序會繼承父程序所建立的管道 有名管道 有...

無名管道(PIPE)與 有名管道(FIFO)

更多資料 我的目錄 1 無名管道的建立 標頭檔案 include 函式原型 int pipe int pipefd 2 引數 pipefd 乙個至少具有兩個int型資料的陣列 pipefd 0 讀端的檔案描述符,只能讀取管道中的資訊 pipefd 1 寫端的檔案描述符,只能往管道中寫入資訊 返回值 ...

管道 無名管道 和FIFO 有名管道

管道是最初的unixipc形式,但是因為管道沒有名字,所以它們只能用於有親緣關係的程序使用 進而有名管道 fifo 應運而生,有名管道有乙個路徑名與之關聯,所以允許無親緣關係的程序訪問同乙個fifo。以下具體介紹管道 管道的建立 管道由函式 int pipe int fd 2 建立,提供乙個單向資料...