管道——命名管道

本文详细介绍了Linux中的FIFO(命名管道)及其工作原理,包括创建、特点、实现方式(如mkfifo函数),以及如何通过文件I/O操作进行通信。重点讨论了半双工与全双工的区别,并给出了简单的编程示例。
摘要由CSDN通过智能技术生成

1、FIFO文件介绍

FIFO文件(也称为命名管道)是一种特殊类型的文件,在linux中用于进程间通信。而FIFO文件允许不相关进程通过读取和写入相同的文件夹来进行通信。

特点:

  • FIFO文件位于文件系统中,可以像其他文件一样进行访问和管理。
  • FIFO文件可以通过名称进行识别和引用,而不仅仅依赖于文件描述符(无名管道只依赖于文件描述符)。
  • FIFO文件可以在不同的进程之间进行双向通信,允许同时进行读取和写入操作(但是容易出现数据混乱,也就是数据会交织在一起)。

2、FIFO实现原理

底层通过mkfifo函数创建一个FIFO文件,FIFO文件对应一个fifo inode,fifo iNode和pipe inode底层实现相同。

命名管道通过文件名创建管道,所以称为命名管道。

命名管道通过mkfifo创建完成之后,进程调用open打开fifo文件,由于每个文件都对应唯一的iNode节点,所以多个进程都是打开相同的iNode节点,成功打开fifo文件之后,进程能正常读写管道完成进程间通信。

打开fifo文件需要知道fifo文件路径,进程间只要知道fifo文件路径,就能建立连接,完成通信。进程之间都能看到管道内存空间,所以进程能正常通信。

 3、FIFO是否支持全双工

  • 调用一次mkfifo函数只能产生一个管道(一个缓冲区),所以命名管道是半双工模式。
  • 多个进程同时读写一个命名管道可能会出现数据异常,所以进程调用open函数时指定打开标志为O_RDONLY或者O_WRONLY
  • 若要实现全双工通信,需要创建多个命名管道。

4、FIFO编程

创建命名管道:
    int mkfifo(const char *pathname, mode_t mode);
功能:
    mkfifo函数是Linux下的一个系统调用函数,用于一个命名管道(FIFO文件)的创建。
参数:
    path:命名管道路径名
    mode:创建的命名管道的权限,可参考open函数
返回值:
    成功:返回0
    失败:返回-1,并设置errno

命名管道使用文件IO open、write、read、close实现打开、写、读、关闭操作。

5、写个例程

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define FIFO_PATH "/home/fqs/UNIX_C/001_FIFO/test"

int fifo_read()
{
    int ret = mkfifo(FIFO_PATH, 0644);
    if(ret == -1 && errno != EEXIST)
    {
        perror("mkfifo");
        return -1;
    }

    int fd = open(FIFO_PATH, O_RDONLY);
    if(fd == -1)
    {
        perror("open");
        return -1;
    }

    while(1)
    {
        char buf[1024] = {0};
        read(fd, buf, 1024);
        printf("read buf = %s\n",buf);
        sleep(1);
    }
    
    return 0;
}

int fifo_write(const char *buf)
{
    int ret = mkfifo(FIFO_PATH, 0644);
    if(ret == -1 && errno != EEXIST)
    {
        perror("mkfifo");
        return -1;
    }

    int fd = open(FIFO_PATH, O_WRONLY);
    if(fd == -1)
    {
        perror("open");
        return -1;
    }

    while(1)
    {
        write(fd, buf, strlen(buf));
        printf("write buf = %s\n",buf);
        sleep(1);
    }
    
    return 0;
}

int main(int argc, char *argv[])
{
    int mode = atoi(argv[1]);
    char *buf = argv[2];
    if(mode == 0)
    {
        fifo_read();
    }
    else if(mode == 1)
    {
        fifo_write(buf);
    }
    
    return 0;
}

传参为0,从管道中读数据,传参为1,向管道写入argv[2]。

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值