linux 进程学习笔记-named pipe (FIFO)命名管道

与“无名管道”不同的是,FIFO拥有一个名称来标志它,所谓的名称实际上就是一个路径,比如“/tmp/my_fifo”,其对应到磁盘上的一个管道文件,如果我们用file命令来查看其文件类型的话,会得到如下输出:

my_fifo: fifo (named pipe)

 

为了简化对FIFO的理解,我们可以这样来假想:进程A在磁盘上创建了一个名为my_fifo的文件,并向其中写入一些数据,然后进程B打开该文件,并将数据从文件中读出,这样我们便实现了进程A和进程B之间的通信。大致原理如此,只不过FIFO做了更精细的一些操作,以便实现起来更可靠.

 

int mkfifo (char* path, mode_t mode)

该函数负责创建FIFO管道,其需要头文件<sys/stat.h>,参数path即要创建的管道文件存放位置,mode参数即文件权限。FIFO管道创建完成以后,便可以使用open函数来打开它,然后进行读写操作了。 

 

下面这个demo,其将测试数据由进程A传递给进程B(为防止混淆视线,我将一些条件判断和异常处理代码删掉了)

先创建一个程序A,其负责创建FIFO管道,并向其中写入一些数据:


/*
 * process A: create FIFO and write data
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define FIFO_NAME "/tmp/my_fifo"
int main()
{
    int pipe_fd;
    //if the pipe file do not exist
    if (access(FIFO_NAME, F_OK) == -1)
    {
        //creat FIFO pipe file
        mkfifo(FIFO_NAME, 0777);
    }
    //open FIFO pipe file.
    //this will be brocked until some one open another end point(read-point) of this pipe
    pipe_fd = open(FIFO_NAME, O_WRONLY);
    //write data into pipe 
    write(pipe_fd, "hi, this is a test", PIPE_BUF);
    //close FIFO pipe file descriptor
    close(pipe_fd);
    return 0;
}

然后创建程序B,它从管道中读取数据并显示出来:


/*
 * process B: read data from FIFO
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "/tmp/my_fifo"
#define BUFFER_SIZE PIPE_BUF
int main()
{
    int pipe_fd;
    char buffer[BUFFER_SIZE + 1];
    //reset all bytes in buffer as '\0' 
    memset(buffer, '\0', sizeof(buffer));
    //open FIFO pipe file.
    //this will be brocked until some one open another end point(write-point) of this pipe
    pipe_fd = open(FIFO_NAME, O_RDONLY);
    if(read(pipe_fd, buffer, BUFFER_SIZE) > 0)
    {
        printf("data from FIFO : %s\n", buffer);
    }
    //close pipe file descriptor
    close(pipe_fd);
    return 0;
}

运行下程序便会发现,无论是先运行A或是B,先运行起来的都会等待另外一个,这时open函数第二个参数的原因,我们可以添加O_NONBLOCK选项来取消阻塞。

 

posted on 2015-11-23 14:29  zyz913614263  阅读(922)  评论(0编辑  收藏  举报

导航