有名管道:
管道的一個不足之處是沒有名字,是以,隻能用于具有 親緣關系的程序間通信,在有名管道提出後,該限制得到了克服。FIFO不同于管道之處在于它提供一個路徑名與之關聯,以FIFO的檔案形式存儲與檔案系統中。有名管道是一個裝置檔案,是以,即使程序與建立FIFO的程序不存在親緣關系,隻要可以通路該路徑,就能夠通過FIFO互相通信。值得注意的是,FIFO總是按照先進先出的原則工作,第一個被寫入的資料将首先從管道中讀出。
1.有名管道的建立與讀寫
Linux下有兩種方式建立有名管道。一是在Shell下互動地建立一個有名管道,二是在程式中使用系統函數建立有名管道。
建立有名管道的系統函數有兩個:mknod和mkfifo。兩個函數均定義在頭檔案sys/stat.h,函數原型如下:
#include<sys/types.h>
#include<sys/stat.h>
int mknod(const char *path,mode_t mod,dev_t dev);
int mkfifo(const char *path,mode_t mode);
mknod&mkfifo函數參數:
path:有名管道的全路徑名;
mod:有名管道的模式,指明其存取權限;
dev為裝置值,該值取決于檔案建立的種類,它隻在建立裝置檔案時才會用到。
傳回:這兩個函數調用成功都傳回0,失敗都傳回-1。
參數值:
“S_IFIFO|0666”指明建立一個有名管道且存取權限為0666,即建立者、與建立者同組的使用者、其他使用者對該有名管道的通路權限都是可讀可寫。
使用有名管道時,必須先調用open()将其打開。調用open()打開有名管道的程序可能會被阻塞,但如果同時用讀寫方式(O_RDWR)打開,則一定不會導緻阻塞;如果以隻讀方式(O_RDONLY)打開,則調用open()函數的程序将會被阻塞直到有寫方打開管道;同樣以寫方式(O_WRONLY)打開也會阻塞直到有讀方打開管道。
2.示例代碼:
使用有名管道在兩個無親緣程序之間通信
procwrite.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#define FIFO_NAME "myfifo"
#define BUF_SIZE 1024
int main()
{
int fd;
char buf[BUF_SIZE]="Hello procwrite,I come from process named procread!";
umask(0);
if(mkfifo(FIFO_NAME,S_IFIFO|0666)==-1)
{
perror("mkfifo error!");
exit(1);
}
if((fd=open(FIFO_NAME,O_WRONLY))==-1)
{
perror("fopen error!");
exit(1);
}
write(fd,buf,strlen(buf)+1);
close(fd);
exit(0);
}
procread.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#define FIFO_NAME "myfifo"
#define BUF_SIZE 1024
int main()
{
int fd;
char buf[BUF_SIZE];
umask(0);
fd=open(FIFO_NAME,O_RDONLY);
read(fd,buf,BUF_SIZE);
printf("Read content:%s\n",buf);
close(fd);
exit(0);
}
運作結果:
1.先運作procwrite,
[email protected]:~/linux_lan/pipe/10.3$ ./procwrite
再運作procread,
[email protected]:~/linux_lan/pipe/10.3$ ./procread
在procread端得到:
Read content:Hello procwrite,I come from process named procread!
在兩個源程式目錄下,出現myfifo檔案。
PS:再次運作需删除myfifo。