当前位置: 首页 > news >正文

Linux管道 有名管道(FIFO)工作机制全解:从理论到实践

有名管道(重要)

有名管道/命名管道,主要用于没有血缘关系进程间的通信

当然也支持有血缘关系的情况,只是如果有血缘关系,没有必要使用有名管道,无名管道效果更佳

引入

好了,现在使用条件有了,该如何实现呢?

不同进程都有自己的独立空间,那如何将不同进程联系起来呢?

可以通过 磁盘内的文件(用于磁盘映射),物理内存,寄存器,数据库,第三方电脑等等,只要是不同进程都可以识别,并不是但属于一个进程的即可。

当然利用不同方式实现肯定是不同的方法,这里主要是带大家一步步地去实现有名管道。

这里我们实现有名管道的方式 是借助物理内存

那么,问题又来了:物理内存是属于底层的,该如何操作物理内存呢?

物理内存偏底层,我们直接操作,我们目前做不到,也不是我们的重点。

我们说过,在Linux一切皆可视为文件,因此在这里我们通过将物理内存抽象为文件名,两个进程通过操作这个文件名,来实现进程间的通信。

因此这时候的物理内存就是一个管道,抽象出来的文件名,也就是有名管道,有名的来源。

这里简单说一下虚拟区别和物理内存的区别

在每个进程开始,系统会为每一个进程分配4GB的虚拟内存空间,这4GB是虚拟的。

而物理内存是切实存在的。

大家可以使用下面这张图来理解

有名管道的概述

特点

  1. 半双工,同一时刻只能在一个方向上流动
  2. 写入FIFO中的数据遵循先入先出的规则
  3. 传送数据无格式,事先必须约定好数据格式,如多少个字节算一个消息等
  4. FIFO在文件系统中作为一个特殊的文件而存在,但是它的实际内存却存放在物理内存
  5. 管道在内存中对应一个缓冲区,系统不同其大小也不同
  6. FIFO读取数据是一次性的,数据一旦被读取,就会被FIFO抛弃,释放其空间以存放更多数据
  7. 使用FIFO的进程退出后,FIFO文件将继续保存在文件系统中以便于以后使用
  8. FIFO 有名字不相关的进程可以通过打开命名管道进行通信

有名管道的API

函数介绍

        #include <sys/types.h>

        #include <sys/stat.h>

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

功能介绍

        用于有名管道文件的创建(将物理内存抽象为文件)

参数

        pathname:FIFO的路径名+文件名

        mode:mode_t类型的权限描述符

返回值

        成功:返回0

        失败:返回-1,并设置errno

代码案例

00_read.c

在我的文件中文件名是 00_Bob.c

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

int main(int argc, char const *argv[])
{
    //创建有名管道文件
    mkfifo("my_fifo",0666);

    //作为收端,以读的方式打开文件
    //这里因为文件是我们创建的,已知文件一定存在,不需要添加O_CREAT行为标志
    int fd = open("my_fifo",O_RDONLY);
    if(fd == -1)
    {
        perror("open");
        _exit(-1);
    }
    printf("收端已准备就绪\n");

    //读数据
    while(1)
    {
        char buf[128] = "";
        read(fd,buf,sizeof(buf));
        printf("读到的数据为:%s\n",buf);
        if(strcmp(buf,"bye") == 0)
        {
            break;
        }
    }

    //关闭文件
    close(fd);
    unlink("my_fifo");
    return 0;
}

00_write.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    //打开有名管道文件 这里我建议读写端都打开文件,因为我们不知道哪个进程会先打开
    //又由于mkfifo文件重复 会返回-1 因此这里我们不进行打开错误判断
    mkfifo("my_fifo",0666);

    //Lucy负责发 以写的方式打开该文件
    int fd = open("my_fifo",O_WRONLY);
    if(fd == -1)
    {
        perror("open");
        _exit(-1);
    }
    printf("发端准备就绪\n");

    //写入数据
    while(1)
    {
        //手动输入数据
        printf("输入数据:");
        char buf[128] = "";
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf) - 1] = 0;

        write(fd,buf,strlen(buf));

        if(strcmp(buf,"bye") == 0)
        {
            break;
        }
    }

    //关闭文件  
    close(fd);
    unlink("my_fifo");
    return 0;
}

代码运行结果:

在我的文件中文件名是 00_Lucy.c

有名管道的读写特点

1、open 以只读方式打开 FIFO 时,要阻塞到某个进程为写而打开此 FIFO 

2、open 以只写方式打开 FIFO 时,要阻塞到某个进程为读而打开此 FIFO

3、open 以只读、只写方式打开 FIFO 时会阻塞,调用 read 函数从 FIFO 里读数据时 read 也会阻塞。

4、通信过程中若进程先退出了,则调用 read 函数从 FIFO 里数据时不阻塞;若写进程又重新运行,则调用 read 函数从 FIFO 里读数据时又恢复阻塞

5、通信过程中,进程退出后,写进程向命名管道内写数据时,写进程也会(收到 SIGPIPE 信号)退出

6、调用 write 函数向 FIFO 里写数据,当缓冲区已满时 write 也会阻塞

解释

打开通道时,必须读端和写端都要打开

打开后

关闭读端,写端一旦写入,会导致写进程退出

关闭写端,读端可以继续读(此时被阻塞),写端重新运行,读端可以读,但会被阻塞

这里大家可以理解为一个水管,写为进水口,读为出水口

出水口堵住了,再向内灌水,水管就会坏,因此会导致进水口也关闭

进水口堵住了,但是出水口仍可以打开,最差的结果也就是不出水

代码思想补充

我们可以知道上面的例子中代码重复部分过多,会显得内容优点冗余,因此为了降低代码的冗余度,我们将上面两个代码合二为一,使用的是条件编译 对代码进行删减

今天时间原因,不给大家进行代码演示了,将在下篇分享中为大家补充,谢谢理解!

我们从上面学习中可以知道管道读写段一旦确定无法修改,我将在下篇博客中 将实现管道双向通信

结束

代码重在练习!

代码重在练习!

代码重在练习!

今天的分享就到此结束了,希望对你有所帮助,如果你喜欢我的分享,请点赞收藏夹关注,谢谢大家!!!

相关文章:

  • java导出postgis空间数据几何对象shapefile文件
  • Spark大数据分析与实战笔记(第四章 Spark SQL结构化数据文件处理-04)
  • Qt中的鼠标事件
  • React七案例中
  • 函数指针数组的用途
  • 【现代深度学习技术】循环神经网络02:文本预处理
  • powerbi制作中国式复杂报表
  • Poission 时间点过程
  • 列表之链表_C
  • 三维空间中的离散曲线段匹配方法
  • 数据库学习
  • 程序化广告行业(73/89):买卖双方需求痛点及应对策略深度剖析
  • 通过可组合的数字体验平台(DXP)提升运营效率与个性化体验
  • echarts地图详解
  • spark课后总结
  • 【Java异步】解决@Async注解,同类下调用不生效
  • python自定义自己的类库
  • 基于django大数据平台的交通数据可视化设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
  • pig 权限管理开源项目学习
  • 第 28 场 蓝桥入门赛 JAVA 完整题解
  • 上海装修公司网站建设/首页关键词优化价格
  • wordpress插件没有设置/深圳百度首页优化
  • 广州网站优化招聘/百度推广技巧
  • web网站怎么做/搭建一个网站平台需要多少钱
  • 郴州市住房建设局门户网站/网站排名软件有哪些
  • 互联网营销师报考条件/seo公司优化排名