天天看點

FIFO 有名管道

有名管道

        在建立管道成功之後,就可以使用open()、read()和write()這些函數了。與普通檔案的開發設定一樣,對于為讀而打開的管道可在open()中設定O_RDONLY,對于為寫而打開的管道可在open()中設定O_WRONLY,在這裡與普通檔案不同的是阻塞問題。

        由于普通檔案的讀寫時不會出現阻塞問題,而在管道的讀寫中卻有阻塞的可能,這裡的非阻塞标志可以在open()函數中設定為O_NONBLOCK。

對于O_RDONLY、 O_WRONLY、 O_NONBLOCK有4種組合方式:

1、open(const char *path,O_RDONLY)

在這種情況下,open 調用将阻塞,除非有一個程序以寫方式打開同一個FIFO,否則它不會傳回

2、open(const char *path,O_RDONLY|O_NONBLOCK )

即使沒有其它程序以寫方式打開FIFO,這open調 用也将成功并馬上傳回

3、open(const char *path,O_WRONLY)

open調用将阻塞,直到有一個程序以讀方式打開同一個 FIFO為止。

4、open(const char *path,O_WRONLY|O_NONBLOCK )

open調用總是立刻傳回,便如果沒有程序以讀方式打開FIFO檔案, open調用将傳回一個錯誤(-1)并且FIFO也不會被打開。

對于讀程序

• 若該管道是阻塞打開,且目前FIFO内沒有資料,則對讀程序而言将一直阻塞到有資料寫入。

• 若該管道是非阻塞打開,則不論FIFO内是否有資料,讀程序都會立即執行讀操作。

對于寫程序

• 若該管道是阻塞打開,則寫操作将一直阻塞到資料可以被寫入。

• 若該管道是非阻塞打開而不能寫入全部資料,則讀操作進行部分寫入或者調用失敗。

例子:

讀程序:(fifoRead.c)運作需要在root使用者下

#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
  if(mkfifo("/tmp/fifo1",O_CREAT|O_EXCL)==-1)
  printf("mkfifo fail...");//第二次會輸出該結果,因為之前建立了。
  int fd = open("/tmp/fifo1",O_RDONLY);//O_WRONLY,O_WRRD....
  char buf[1024];
  memset(buf,'\0',sizeof(buf));
  if ( fd == -1)
  {
    printf("open fail...");
  }
  else
  {
    read(fd,buf,sizeof(buf));
    printf("buf is %s\n",buf);
  }
  return 0;
}
           

寫程序(fifoWrite.c):(讀程序和寫程序是2個程序,是以需要在2個終端分别運作)

#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>


int main()
{
        int fd = open("/tmp/fifo1",O_WRONLY);//O_WRONLY,O_WRRD....
        if ( fd == -1)
        {
                printf("OPEN fail...");
        }
        else
        {
                write(fd,"123",3);
        }
        return 0;
}