在之前的部落格中介紹了程序通訊中的無名管道通訊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中設立了乙個專門的特殊檔案系統 管道檔案,它存在於檔案系統中,任何程序可以在任何時候通過有名管道的路徑和檔案...