命名管道 FIFO (First In First Out)
指令行: mknod
mknod [-m mode] NAME TYPE [ MAJOR MINOR]
mknod name b | c major minor //塊裝置,字元裝置檔案
mknod name p //管道檔案
mknod name s //信号量
mknod name m //共享記憶體
指令行:mkfifo (first input first output)
mkfifo [-m mode] name //建立命名管道
mode 即檔案通路權限, 如 mkfifo –m 644 k2
指令行測試管道通信
mknod pnod p
tty1: cat pnod
tty2: echo Message > pnod
注:管道無内容時,讀阻塞;管道寫入内容,沒有讀出之前,寫阻塞
管道建立函數
<sys/types.h>
<sys/stat.h>
int mkfifo (const char *pathname, mode_t mode)
和指令行一樣:
向管道中寫入資料後,沒有被讀出,則阻塞
從管道中讀出資料時,如果沒資料,則阻塞
思路:
命名管道檔案使用,和讀寫檔案操作類似, 步驟如下:
1: 建立管道檔案 mkfifo()
2: 打開管道
程序a:隻讀打開管道檔案 open 或 fopen
程序b:隻寫打開管道檔案
3: 讀寫管道
程序a:讀管道 read, fread
程序b:寫管道 write, fwrite
4: 關閉管道 close, fclose
管道模型
1-1 模型
兩個程序間雙向通信
需要兩個管道
n-1 模型
非互動式服務:多個用戶端向服務端發送消息
1 個管道,用戶端向服務端單向通信
n-1-n 模型
互動式服務:
1:多個用戶端 共用管道向服務端發送消息
2:服務端通過專用管道向用戶端發送消息
例子:兩個程序間通信,要啟動兩次程式,隻有單向通信。
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
void testPipe()
{
char cMode;
fprintf(stderr,"select the mode:w/r:");
cMode=getchar();
char szFile[128]={"pnod"};
int fd;
int len;
char szBuf[1024];
struct stat info;
//不存在名為pnod的檔案
if(!stat(szFile,&info))
{
//建立名為pnod的管道檔案
if(!mkfifo(szFile,0664))
{
perror("fail mkfifo!");
return ;
}
}
//存在該檔案,但不是管道檔案
else if(!S_ISFIFO(info.st_mode))
perror("this is not a pipe file");
return ;
//接受方
if(cMode=='r')
//打開檔案,傳回檔案描述符
fd=open(szFile,O_RDONLY);
if(fd<0)
perror("fail open!");
while(1)
memset(szBuf,0,sizeof(szBuf));
len=read(fd,szBuf,sizeof(szBuf));
if(len<0)
{
perror("fail to read file!");
return ;
}
else if(len==0)
printf("FIFO closed!\n");
else
printf("receive:%s",szBuf);
close(fd);
//發送方
else if(cMode=='w')
fd=open(szFile,O_WRONLY);
fprintf(stderr,"Send:");
read(0,szBuf,sizeof(szBuf));
write(fd,szBuf,strlen(szBuf));
else
}
int main()
testPipe();
return 0;