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!");

                 return ;

           }

           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! ");

                      return ;

                 }

                 else

                 {

                      printf("receive:%s",szBuf);

                 }

           }

           close(fd);

          

                

      }

      //发送方

      else if(cMode=='w')

      {

          

           fd=open(szFile,O_WRONLY);

           if(fd<0)

           {

                 perror("fail open!");

                 return ;

           }

           while(1)

           {

                 fprintf(stderr,"Send:");

                 memset(szBuf,0,sizeof(szBuf));

                

                 read(0,szBuf,sizeof(szBuf));

                 write(fd,szBuf,strlen(szBuf));

           }

           close(fd);

      }

      else

      {

           return ;

      }

}

int main()

{

      testPipe();

      return 0;

}

原文地址:https://www.cnblogs.com/gd-luojialin/p/9216013.html