天天看點

linux學習之十九---有名管道

有名管道:

管道的一個不足之處是沒有名字,是以,隻能用于具有 親緣關系的程序間通信,在有名管道提出後,該限制得到了克服。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。

繼續閱讀