FIFO

FIFO常被称为命名管道,以区分管道(pipe)

管道(pipe)只能用于“有血缘关系”的进程间。

但通过FIFO,不相关的进程也能交换数据。  

FIFOLinux基础文件类型中的一种。但,FIFO文件在磁盘上没有数据块,仅仅用来标识内核中一条通道。

各进程可以打开这个文件进行read/write,实际上是在读写内核通道,这样就实现了进程间通信。

创建方式: 

1. 命令:mkfifo 管道名 

 2. 库函数:int mkfifo(const char *pathname, mode_t mode);  成功:0;失败:-1 

 一旦使用mkfifo创建了一个FIFO,就可以使用open打开它,常见的文件I/O函数都可用于fifo

如:closereadwriteunl

 

DEMO 模拟无血缘关系的进程间通信

#include <iostream>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include <cstring>

#include <string>

 

using namespace std;

 

string get_time(){

 

       struct tm * c_time;

    char buf[666];

       time_t t;

     time(&t);

      c_time = localtime(&t);

       strftime(buf, sizeof(buf), "%F %T", c_time);

       return string(buf);

}

 

int main(int argv, char * args[]){

 

       if(argv < 2){

              perror("input like ./fifo_test read");

              exit(1);

       }

 

       if(access("test", F_OK) == -1 && mkfifo("test", 0664) == -1){

              perror("mkfifo error");

              exit(1);

       }

 

       if(strcmp(args[1], "write") == 0){

              pid_t pid = fork();

              if(pid == -1){

                     perror("fork error");

                     exit(1);

              }else if(pid == 0){

                     int fd = open("test", O_RDWR);

                     string str; 

                     while(true){

                            str = get_time();  

                            write(fd, str.data(), str.length());

                            sleep(1);

                     }

 

              }

 

       }else if(strcmp(args[1], "read") == 0){

              int fd = open("test", O_RDWR);

              char buf[BUFSIZ];

              int len = 0;

              while(true){

                     len = read(fd, buf, sizeof(buf));  

                     buf[len] = '\0';

                     cout << "read from fifo file" << endl;

                     cout << "data: " << buf << endl;

                     cout << "size: " << len << endl;

                     cout << flush;

              }

 

       }else{

              perror("argument error");

              exit(1);

       }

 

       return 0;

}