天天看點

20命名管道

命名管道 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;