FIFO簡介:
FIFO,即命名管道, 也是Linux系統的一種程序間通信方式,不同于匿名管道,命名管道可以進行“非父/子關系”程序間通信,而且以檔案節點的形式在。使用mkfiifo可以建立這個檔案節點檔案。
First In First Out的縮寫,意為先進先出,正好是指令管道的特點。
命名管道是一個特殊的檔案節點:
要使用FIFO,先建立fifo檔案,讀端通過read來從fifo讀取(類似于檔案讀取);寫端通過read來從fifo讀取(類似于檔案寫入)。
下面是一個命名管道檔案:
fifo1.lnk
fifo1.lnk就是建立的管道,可見,字尾是lnk檔案。命名管道以一種特殊的檔案形式存在,在提供管道功能的同時,也具有了普通檔案的優點(可以同時被多個程序夾享)。
mkfifo函數聲明:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo( const char* pathname, mode_t mode );
功能:建立命名管道,即“在檔案系統中建立一個檔案,該檔案用于提供FIFO功能”。
參數:
第一個參數(pathname)是将要在檔案系統中建立的一個專用檔案;
第二個參數(mode)用來規定FIFO的讀寫權限。
傳回值:
如果調用成功的話,傳回值為0;
如果調用失敗傳回值為-1。
FIFO使用舉例:
下面我們以一個執行個體來說明如何使用mkfifo函數建一個FIFO,以及進行FIFO的讀寫。
實作兩個c檔案,分别進行讀和寫,在讀端進行FIFO檔案節點的建立,并讀取資料;在寫端把資料寫入FIFO檔案節點。
read_fifo.c(讀端):
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
/* 讀 */
int main()
{
int fd;
int len;
char buf[1024];
if(mkfifo("fifo1", 0666) < 0 && errno!=EEXIST) // 建立FIFO管道
perror("Create FIFO Failed");
if((fd = open("fifo1", O_RDONLY)) < 0) // 以讀打開FIFO
{
perror("Open FIFO Failed");
exit(1);
}
while((len = read(fd, buf, 1024)) > 0) // 讀取FIFO管道
printf("Read message: %s", buf);
close(fd); // 關閉FIFO檔案
return 0;
}
讀端調用mkfifo和read。fifo1就是建立的管道。
write_fifo.c(寫端):
#include<stdio.h>
#include<stdlib.h> // exit
#include<fcntl.h> // O_WRONLY
#include<sys/stat.h>
#include<time.h> // time
int main()
{
int fd;
int n, i;
char buf[1024];
time_t tp;
printf("I am %d process.\n", getpid()); // 說明程序ID
if((fd = open("fifo1", O_WRONLY)) < 0) // 以寫打開一個FIFO
{
perror("Open FIFO Failed");
exit(1);
}
for(i=0; i<10; ++i)
{
time(&tp); // 取系統目前時間
n=sprintf(buf,"Process %d's time is %s",getpid(),ctime(&tp));
printf("Send message: %s", buf); // 列印
if(write(fd, buf, n+1) < 0) // 寫入到FIFO中
{
perror("Write FIFO Failed");
close(fd);
exit(1);
}
sleep(1); // 休眠1秒
}
close(fd); // 關閉FIFO檔案
return 0;
}
寫端調用open和write。
編譯和運作:
分别用gcc編譯,得到兩個可執行程式:一個read ,一個write,分别用于讀寫。
read的運作結果:
Read message: Process 3372's time is Thu July 15 07:35:08 2010
Read message: Process 3372's time is Thu July 15 07:35:09 2010
Read message: Process 3372's time is Thu July 15 07:35:10 2010
Read message: Process 3372's time is Thu July 15 07:35:11 2010
Read message: Process 3372's time is Thu July 15 07:35:12 2010
write的運作結果:
I am 3372 process.
Send message: Process 3372's time is Thu July 15 07:35:08 2010
Send message: Process 3372's time is Thu July 15 07:35:09 2010
Send message: Process 3372's time is Thu July 15 07:35:10 2010
Send message: Process 3372's time is Thu July 15 07:35:11 2010
Send message: Process 3372's time is Thu July 15 07:35:12 2010
可見,在read中,建立管道,并且讀取資料; 在write中,向管道寫入資料。