• fifo


    命名管道

    FIFO常被称为命名管道, 以区分管道(pipe). 管道(pipe)只能用于"有血缘关系"的进程间. 但通过FIFO, 不相关的进程也能交换数据

    FIFO是linux基础文件类型中的一种. 但FIFO文件在磁盘上没有数据块, 仅仅用来标识内核中一条通道. 各个进程可以打开这个文件进程read/write, 实际上是在读写内核通道, 这样就实现了进程间的通信

    特点
      有名管道
      在磁盘上有这样一个文件
      伪文件, 在磁盘上大学为0
      在内核中有一个对应的缓冲区
      半双工的通信方式

    使用场景
      没有血缘关系的进程间通信

    创建方式
      命令: mkfifo管道名
      函数: int mkfifo(const char *pathname, mode_t mode);

    fifo文件可以使用IO函数进行操作
      open/close
      read/write
      不能执行lseek操作

    进程间通信
      两个不相干的进程, 进程A(a.c)和进程B(b.c)
      a.c:

    int fd = open("mufifo", O_RDONLY);
    read(fd, buf, sizeof(buf));
    close(fd);
    

      b.c

    int fd = open("myfifo", O_WRONLY);
    write(fd, "Hello World", 11);
    close(fd)
    

    注意: a.c和b.c中open的文件需要打开一个fifo

    实例程序

    测试时要先关闭读端再关闭写端, 否则写端关闭后读端一直读0

    写端

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <fcntl.h>
    
    int main(int argc, const char *argv[]) {
        if (argc < 2) {
            printf("./a.out, fifoname
    ");
            exit(1);
        }
        
        int ret = access(argv[1], F_OK);    // 判断文件是否存在
        if (ret == -1) {
            int r = mkfifo(argv[1], 0664);  // 创建fifo
            if (r == -1) {
                perror("mkfifo error");
                exit(1);
            }
            printf("有名管道%s创建成功
    ", argv[1]);
        }
        
        int fd = open(argv[1], O_WRONLY);
        if (fd == -1) {
            perror("open error");
            exit(1);
        }
    
        char *p = "haha";
        while (1) {
            //int len = write(fd, p, sizeof(p));    // 好像和编码方式有关
            int len = write(fd, p, strlen(p)+1);
            printf("write: %s
    len = %d
    ", p, len);
            sleep(1);
        }
        
        close(fd);
    
        return 0;
    }
    

    读端

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <fcntl.h>
    
    int main(int argc, const char *argv[]) {
        if (argc < 2) {
            printf("./a.out, fifoname
    ");
            exit(1);
        }
        
        int ret = access(argv[1], F_OK);    // 判断文件是否存在
        if (ret == -1) {
            int r = mkfifo(argv[1], 0664);  // 创建fifo
            if (r == -1) {
                perror("mkfifo error");
                exit(1);
            }
            printf("有名管道%s创建成功
    ", argv[1]);
        }
        
        int fd = open(argv[1], O_RDONLY);
        if (fd == -1) {
            perror("open error");
            exit(1);
        }
    
        char buf[512];
        while (1) {
            int len = read(fd, buf, sizeof(buf));
            buf[len] = 0;
            printf("read: %s
    len = %d
    ", buf, len);
        }
    
        close(fd);
    
        return 0;
    }
    
  • 相关阅读:
    centos7安装kubenetes
    用户密码字典
    curl使用
    docker部署rabbitmq集群
    记一次使用docker搭建fastdfs服务的过程
    filebeat删除多余标签
    Python format格式化输出
    python3 统计NGINX pv uv 最多IP访问
    linux修改网卡名为eth0
    模式查找
  • 原文地址:https://www.cnblogs.com/hesper/p/10738861.html
Copyright © 2020-2023  润新知