Linux管道(具名FIFO)

概述

    (匿名)管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。

    如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道;命名管道是一种特殊类型的文件.

 

管道应用

1)创建一个命名管道

命名管道可以从命令行上创建:

$ mkfifo <filename>

 

命名管道在程序里创建:

       #include <sys/types.h>

       #include <sys/stat.h>

 

       int mkfifo(const char *pathname, mode_t mode);


 

匿名管道 VS. 命名管道

1) 匿名管道由pipe函数创建并打开。

    命名管道由mkfifo函数创建,打开用open

2) FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

 

命名管道的打开规则

 

1)读打开FIFO

    O_NONBLOCK disable(阻塞):阻塞直到有相应进程为写而打开该FIFO

    O_NONBLOCK enable(非阻塞):立刻返回成功

 

2)写打开FIFO

    O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO

    O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

 

命名管道的读写规则

    同匿名管道

 

 

FIFO编程实践

/**说明:利用管道,两个进程间进行文件复制。
进程writefifo:
  读input.txt文件
	写入管道fifo
进程readfifo:	
	读管道fifo
	写入output.txt文件
*/

//1:writefifo
//write fifo, read from file
int main()
{
    //创建FIFO
    if (mkfifo("./myFifo",0644) == -1)
    {
        err_exit("mkfifo error");
    }

    //打开管道
    int fifofd = open("./myFifo",O_WRONLY);
    if (fifofd == -1)
    {
        err_exit("open fifo error");
    }
    //打开文件
    int filefd = open("./input.txt",O_RDONLY);
    if (filefd == -1)
    {
        err_exit("open file error");
    }

    //const int BUFSIZ = 1024;
    char buf[BUFSIZ];
    int readCount = 0;
    while ((readCount = read(filefd,buf,BUFSIZ)) > 0)
    {
        write(fifofd,buf,readCount);
    }

    close(fifofd);
    close(filefd);

    cout << "Write FIFO OK..." << endl;
    return 0;
}

//2:readfifo
//read fifo, write to file
int main()
{
    //打开FIFO
    int fifofd = open("./myFifo",O_RDONLY);
    if (fifofd == -1)
    {
        err_exit("open fifo error");
    }
    //打开文件
    int filefd = open("./output.txt",O_WRONLY|O_CREAT,0644);
    if (filefd == -1)
    {
        err_exit("open file error");
    }

    char buf[BUFSIZ];
    int readCount = 0;
    while ((readCount = read(fifofd,buf,BUFSIZ)) > 0)
    {
        write(filefd,buf,readCount);
    }

    close(fifofd);
    close(filefd);

    cout << "Read FIFO OK..." << endl;

    return 0;
}

-FIFO手册页(man 3 mkfifo)

MKFIFO(3)                           Linux Programmer‘s Manual                          MKFIFO(3)

NAME
       mkfifo - make a FIFO special file (a named pipe)

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

       int mkfifo(const char *pathname, mode_t mode);

DESCRIPTION
       mkfifo() makes a FIFO special file with name pathname.  mode specifies the FIFO‘s permissions.  It is modified by the process‘s umask in the usual way: the  permissions  of  the created file are (mode & ~umask).
       A  FIFO  special file is similar to a pipe, except that it is created in a different way.
       Instead of being an anonymous communications channel, a FIFO special file is entered into the filesystem by calling mkfifo().
       Once  you have created a FIFO special file in this way, any process can open it for reading or writing, in the same way as an ordinary file.  However, it has to be open at  both ends  simultaneously  before  you can proceed to do any input or output operations on it.
       Opening a FIFO for reading normally blocks until some other process opens the  same  FIFO for writing, and vice versa.  See fifo(7) for nonblocking handling of FIFO special files.

RETURN VALUE
       On  success  mkfifo() returns 0.  In the case of an error, -1 is returned (in which case, errno is set appropriately).


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。