Linux 程序通訊 命名管道

2021-07-14 10:46:39 字數 3332 閱讀 9105

在之前的部落格中介紹了程序通訊中的無名管道通訊pipe,也對無名管道的侷限性進行了剖析。

在這裡,提出命名管道的概念fifo,可解決無名管道的侷限性,命名管道到底是通過什麼機制進行通訊的?請看下面

命名管道(fifo)

————顧名思義,first input first output,按照先進先出的原則工作,第乙個被寫入的資料將首先從管道中讀出。

1.概念

管道的乙個不足之處是沒有名字,因此,只能用於具有親緣關係的程序間通訊,在命名管 道(named pipe或fifo)提出後,該限制得到了克服。fifo不同於管道之處在於它提供乙個路徑名與之關聯,以fifo的檔案形式儲存於檔案系統中。命名管道是乙個裝置檔案,因此,即使程序與建立fifo的程序不存在親緣關係,只要可以訪問該路徑,就能夠通過fifo 相互通訊。

2.命名管道的建立與讀寫

linux下有兩種⽅方式建立命名管道。一是在shell下互動地建立乙個命名管道;

二是在程式中使⽤用系統函式建⽴立命名管道。shell⽅方式下可使⽤用mknod或mkfifo命令。

下⾯面命令使⽤用 mknod建立了⼀乙個命名管道:

mknod namedpipe

建立命名管道的系統函式有兩個:mknod和mkfifo。

兩個函式均定義在頭⽂檔案sys/stat.h, 函式原型如下:

#include #include int mknod(const char *path,mode_t mod,dev_t dev);

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

函式mknod引數中path為建立的命名管道的全路徑名:mod為建立的命名管道的模式,指明其訪問許可權;dev為裝置值,該值取決於檔案建立的種類,它只在建立裝置檔案時才會用到。

mknod和mkfifo兩個函式呼叫成功都返回0,失敗都返回  -1。

下面使用mknod函式建立了⼀個命名管道:

umask(0)

if (mknod("/tmp/fifo",s_ififo | 0666) == -1)

函式mkfifo前兩個引數的含義和mknod相同下面是使用mkfifo的示例**:

umask(0); 

if (mkfifo("/tmp/fifo",s_ififo|0666) == -1)

s_ififo|0666  指明建立乙個命名管道且訪問許可權為0666,即建立者,與建立者同組的使用者,其他使用者對該命名管道的訪問許可權都是可讀可寫(注意umask對生成的管道檔案許可權的影響)

命名管道建立後就可以使⽤用了,命名管道和管道的使用方法基本是相同的。只是使用命 名管道時,必須先調⽤用open()將其開啟。因為命名管道是乙個存在於硬碟上的檔案,而管道 是存在於記憶體中的特殊檔案。    

注意,呼叫open()開啟命名管道的程序可能會被阻塞。但如果同時用讀寫方式 (o_rdwr)開啟,則一定不會導致阻塞;如果以唯讀方式(o_rdonly)開啟,則呼叫open()函式的程序將會被阻塞直到有寫方開啟管道;同樣以寫方式(o_wronly)開啟也會阻塞直到有讀方式開啟管道。

三.總結

檔案系統中的路徑名是全域性的,各程序都可以訪問,因此可以用檔案系統中的路徑名來標識⼀一 個ipc通道。  命名管道也被稱為fifo檔案,它是一種特殊型別的檔案,它在檔案系統中以檔名的形式存在,但是它的行為卻和之前所講的沒有名字的管道(匿名管道)類似。 由於linux中所有的事物都可被視為⽂檔案,所以對命名管道的使用也就變得與檔案操作非常的統⼀,也使它的使用非常方便,同時我們也可以像平常的檔名⼀樣在命令中使用。

建立命名管道可以用兩個函式,函式原型如下:

#include #include int mkfifo(const char *filename, mode_t mode);  

int mknod(const char *filename, mode_t mode | s_ififo, (dev_t)0);

這兩個函式都能建立⼀乙個fifo檔案,注意是建立⼀乙個真實存在於檔案系統中的檔案, filename指定了檔名,而mode則指定了檔案的讀寫許可權。mknod是比較老的函式,而使用 mkfifo函式更加簡單和規範,所以建議在可能的情況下,盡量使用mkfifo而不是mknod。 mkfifo函式的作用是在檔案系統中建立⼀乙個檔案,該檔案⽤用於提供fifo功能,即命名管道。 前邊講的那些管道都沒有名字,因此它們被稱為匿名管道,或簡稱管道。對檔案系統來說, 匿名管道是不可見的,它的作用僅限於在父程序和子程序兩個程序間進行通訊。⽽命名管道是乙個可見的⽂檔案,因此,它可以用於任何兩個程序之間的通訊,不管這兩個程序是不是⽗子程序,也不管這兩個程序之間有沒有關係。

fifo read端:

#include #include #include #include #include #include #define _path_ "/tmp/file.tmp" 

#define _size_ 100

int main()

char buf[_size_];

memset(buf, '\0', sizeof(buf));

while(1)

printf("%s\n", buf);

if( strncmp(buf, "quit", 4) == 0 )

}           

close(fd);   

return 0;         

}

fifowrite端:

#include #include #include #include #include #include #define _path_ "/tmp/file.tmp" 

#define _size_ 100

int main()

int fd = open(_path_, o_wronly);

if(fd < 0)

char buf[_size_];

memset(buf, '\0', sizeof(buf));

while(1)

if( strncmp(buf, "quit", 4) == 0 )

}

close(fd);

return 0;

}

Linux程序間通訊 命名管道

ipc 命名管道 一 原理 管道的乙個不足之處是沒有名字,因此,只能用於具有親緣關係的程序間通訊,在命名管道 named pip 或fifo 提出後,該限制得到了克服。fifo 不同於管道之處 在於它提供乙個路徑名與之關聯,以fifo的檔案形式儲存於檔案系統中 命名管道是乙個裝置檔案,因此,即使程序...

linux程序間通訊(命名管道)

在處理程序間通訊的問題時,匿名管道只能在有親緣關係的程序中進行通訊。如何做到在任意兩個程序之間通訊,這就要用到命名管道。命名管道也被稱為fifo檔案,它是一種特殊型別的檔案,在檔案系統中以檔案的形式存在,它的行為和匿名管道類似。可以使用mkfifo函式來建立乙個命名管道。int mkfifo con...

linux程序間通訊 命名管道

命名管道也被稱為fifo檔案,它是一種特殊型別的檔案,它在檔案系統中以檔名的形式存在,但是它的行為卻和之前所講的沒有名字的管道 匿名管道 類似。有名管道是有名有形的,為了使用這種管道linux中設立了乙個專門的特殊檔案系統 管道檔案,它存在於檔案系統中,任何程序可以在任何時候通過有名管道的路徑和檔案...