程序通訊之命名管道(FIFO)
阿新 • • 發佈:2018-12-25
匿名管道只能於有血緣關係的程序,那麼倆個沒有任何關係的程序怎麼通訊,這就出現了命名管道來克服這一問題。命名管道是一個裝置檔案,只要訪問該路徑,就能通過這個共享資源來互相通訊。FIFO是按照先進先出的原則工作的,第一個被寫入的資料第一個先被讀出。FIFO可被用於複製序列管道命令之間的輸出流,於是也就不需要寫資料到中間磁碟檔案中(類似於使用管道以避免中間的磁碟檔案);
命名管道的建立:
在shell下互動的建立命名管道
mkfifo命令建立管道:
mknod命令建立管道:
mknod [OPTION]... NAME TYPE [MAJOR MINOR]
option 有用的就是 -m 了
name 自定義
type 有 b (塊裝置),c(字元裝置), p(管道)
在程式中使用系統函式建立命名管道
int mknod(const *filename, mode_t mode | S_IFIFO,(dev_t)0); int mkfifo(const char *filename,mode_t mode) mknod是比較老的函式,經常使用的是mkfifo(更加簡單和規範)這裡著重理解mkfifo這個函式。 filename為建立命名管道的全路徑名,比如在當前路徑下建立一個名為mypipe的管道,filename的值為"./mypipe" 建立管道:命名管道的使用: 與匿名管道的使用方法基本是相同的,不過使用命名管道時需要先呼叫open()開啟;呼叫open時需要注意的是,呼叫open()開啟命名管道的程序可能會被阻塞,但如果同時用讀寫方式(O_RDWR)開啟,則不一定會導致阻塞;如果以只讀方式(O_RDONLY)/(O_WRONLY)開啟,則呼叫open()函式的程序會將被阻塞直到有寫/讀方式開啟管道; 接下來會建立兩個程序來驗證沒有血緣關係的兩個程序通訊; 程序1:#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> int main() { //umask(0); if(mkfifo("./mypipe",S_IFIFO | 0666) < 0){ perror("mkfifo\n"); return -1; } return 0; }
#include<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<string.h> #include<unistd.h> #include<fcntl.h> int main() //client read { int fd = open("./mypipe",O_RDONLY); if(fd < 0){ perror("open\n"); return -2; } char buf[100]; memset(buf,'\0',sizeof(buf)); while(1) { buf[0] = 0; int ret = read(fd,buf,sizeof(buf)); if(ret <0){ perror("write error\n"); } printf("sever:%s\n",buf); } close(fd); return 0; }
程序2:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main() //sever write
{
umask(0);
if(mkfifo("./mypipe",S_IFIFO | 0666) < 0){
perror("mkfifo\n");
return -1;
}
int fd = open("./mypipe",O_WRONLY);
if(fd < 0){
perror("open\n");
return -2;
}
char buf[100];
memset(buf,'\0',sizeof(buf));
while(1)
{
buf[0] = 0;
scanf("%s",buf);
if(write(fd,buf,sizeof(buf))<0){
perror("write error\n");
return -3;
}
//sleep(1);
}
close(fd);
return 0;
}
兩程序通訊:
命名管道是一個可見的檔案,因此,它可以用於任何兩個程序間進行通訊。