【Linux进程间通信】三、FIFO命名管道

简介: 【Linux进程间通信】三、FIFO命名管道

1. 什么是FIFO

FIFO命名管道,也叫有名管道,来区分管道pipe。管道pipe只能用于有血缘关系的进程间通信,但通过FIFO可以实现不相关的进程之间交换数据。FIFO是Linux基础文件类型中的一种,但是FIFO文件在磁盘上没有数据块,仅仅用来标识内核中的一条通道。各进程可以打开这个文件进行read/write操作,实际上是在读写内核通道,这样就实现了进程间通信。

创建FIFO的方式:

  • 使用命令创建:mkfifo 管道名,可以理解为创建一个管道伪文件。
  • 使用库函数创建:mkfifo()函数,并且一旦使用mkfifo()创建了一个FIFO,就可以使用open来打开它,常见的文件I/O函数都可用于FIFO。如:close、read、write、unlink等。

实际上,创建一个FIFO命名管道的时候,内核会为FIFO(伪)文件开辟一个缓冲区,操作FIFO文件就相当于操作这个缓冲区,以此来实现进程间的通信,这种通信实际上就是文件读写的操作来实现的。(可以把FIFO理解为一个文件,一个进程向该文件写数据,另一个进程从该文件中读书数据,前提是两个进程读写的是同一个FIFO文件才能实现通信)

2. FIFO编程实战

示例: 使用FIFO实现进程间通信

创建两个进程,一个进程向FIFO写数据,一个进程从FIFO读数据。

/************************************************************
  >File Name  : write_fifo.c
  >Author     : Mindtechnist
  >Company    : Mindtechnist
  >Create Time: 2022年05月21日 星期六 22时38分08秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("not fount fifoname\n");
        return -1;
    }
    /*打开一个fifo文件*/
    int fd = open(argv[1], O_WRONLY);
    /*写FIFO文件*/
    char buf[256];
    int count = 1;
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        /*循环写入*/
        sprintf(buf, "count %04d", count++);
        /*写入FIFO*/
        write(fd, buf, strlen(buf));
        sleep(1);
    }
    close(fd);
    return 0;
}
/************************************************************
  >File Name  : read_fifo.c
  >Author     : Mindtechnist
  >Company    : Mindtechnist
  >Create Time: 2022年05月22日 星期日 09时54分37秒
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char* argv[])
{
    if(argc < 2)
    {
        printf("not found fifoname\n");
        return -1;
    }
    int fd = open(argv[1], O_RDONLY);
    char buf[256] = {0};
    int ret;
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        ret = read(fd, buf, sizeof(buf));
        if(ret > 0)
        {
            printf("read buf: %s\n", buf);
        }
    }
    close(fd);
    return 0;
}

编译两个程序生成可执行文件,并使用命令mkfifo创建一个FIFO

测试的时候,我们在SecureCRT中克隆一个会话(相当于在Linux中打开两个shell终端),一个运行写进程,一个运行读进程。要注意的是,应该先运行写进程再运行读进程。

同时我们也可以打开多个进程去读写这同一个FIFO缓冲区,当多个进程去读的时候,被读进程1读走的数据就不会再被进程2读取了,比如说下面图中所示,这个进程读到的是36 38 40,而另一个进程读到的是37 39 41。(也可以开启多个写进程去写,读者可自行测试)

我们在读写FIFO的时候都使用了open()函数,使用open函数的时候有一个注意事项,使用open打开FIFO文件的时候,read端会阻塞等待write端open打开文件,直到write进程也使用open打开FIFO的时候,read进程中的open才会返回,反过来也是一样。我们可以在open函数的前后分别打印一句话来测试,只有读端写端都open了FIFO,第二个printf()语句才能打印。实际上只要有一个write和一个read打开了FIFO,就可以,不管是同一个进程还是多个进程。

printf("hello open...\n");
int fd = open(argv[1], O_WRONLY);
printf("bye open...\n");

附:Makefile

通过一个makefile编译多个程序

.PHONY:all clean
CC=gcc
CFLAGS=-Wall -g
EXE=write_fifo read_fifo
all:$(EXE)
%.o:%.c
  $(CC) $(CFLAGS) -c $< -o $@
clean:
  -@rm -f *.o $(EXE)


相关文章
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
381 0
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
430 0
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
317 0
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
401 0
|
12月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
1090 1
二、Linux文本处理与文件操作核心命令
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
800 137
|
12月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1741 58
|
11月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
1687 2
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
934 16

热门文章

最新文章