Linux命名管道方式

 更新时间:2025年03月20日 11:14:57   作者:s_little_monster_  
这篇文章主要介绍了Linux命名管道方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、命名管道

1、与匿名管道的关系

命名管道由mkfifo创建,是一个文件,打开要用open打开

命名管道与匿名管道之间唯一的区别就是它们创建和打开的方式不同,其他基本上相同

命名管道也只能和有“血缘”的进程进行通信

2、工作原理

通过mkfifo创建,会生成一个文件,这就是我们的命名管道文件,它的大小为0

可以看到它的第一列为p,说明它是特殊文件

在我们对普通文件进行打开的时候,我们要进行的结构其实是这样的

其中这个刷盘的过程就是文件缓冲区中的数据刷新到硬盘上的过程,而我们的fifo文件即命名管道文件是没有刷盘的,所以数据只会待在文件缓冲区里,因为在Linux中,多个进程打开同一个文件所指向的文件缓冲区只有一个,所以如果此时再有一个进程以读方式打开fifo文件,它们之间就会以文件缓冲区作为纽带连接,形成了一个结构,这个结构,与我们以前所讲的匿名管道形成的管道结构是一摸一样的

3、系统调用接口

#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
// filename:文件路径
// mode:文件权限
// 返回值:如果管道创建成功返回0,如果失败返回-1并设置errno

4、实现两个进程间通信

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

#define FIFO_NAME "myfifo"
#define BUFFER_SIZE 256

int main()
{
    char message[BUFFER_SIZE];

    // 创建命名管道
    if (mkfifo(FIFO_NAME, 0666) == -1)
    {
        if (errno != EEXIST)
        {
            perror("mkfifo");
            return 1;
        }
    }

    // 打开命名管道以进行写入操作
    int fd = open(FIFO_NAME, O_WRONLY);
    if (fd == -1)
    {
        perror("open");
        return 1;
    }

    // 获取用户输入的消息
    while (1)
    {
        printf("Enter a message to send: ");
        fgets(message, BUFFER_SIZE, stdin);
        message[strcspn(message, "\n")] = 0; // 移除换行符

        // 向命名管道写入消息
        if (write(fd, message, strlen(message)) == -1)
        {
            perror("write");
            close(fd);
            return 1;
        }

        printf("Message sent successfully.\n");
    }
    // 关闭命名管道
    close(fd);

    return 0;
}
  • testr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define FIFO_NAME "myfifo"
#define BUFFER_SIZE 256

int main()
{
    int fd;
    char buffer[BUFFER_SIZE];

    // 打开命名管道以进行读取操作
    fd = open(FIFO_NAME, O_RDONLY);
    if (fd == -1)
    {
        perror("open");
        return 1;
    }
    while (1)
    {
        // 从命名管道读取消息
        ssize_t bytes_read = read(fd, buffer, BUFFER_SIZE - 1);
        if (bytes_read == -1)
        {
            perror("read");
            close(fd);
            return 1;
        }
        buffer[bytes_read] = '\0'; // 添加字符串结束符

        // 输出接收到的消息
        if(buffer[0] == 0)  break;
        printf("Received message: %s\n", buffer);
    }
    // 关闭命名管道
    close(fd);

    // 删除命名管道
    if (unlink(FIFO_NAME) == -1)
    {
        perror("unlink");
        return 1;
    }

    return 0;
}

二、可变参数列表

我们后面要借助命名管道来写一个日志文件,我们需要用到可变参数列表的知识,在这里详细解释一下

可变参数列表允许函数接受不定数量和类型的参数,一般在使用时放到最后面,例如我们前面在进程中断中的函数:

int execl(const char *path, const char *arg, ...);

我们现在有“表”的概念,只要是一个表,最后一个元素一定是NULL,来标志着这个表的结束

与其相关的关键元素有以下四个:(头文件stdarg.h

  • va_list :va_list 是一种自定义类型(通常为指针类型),用于声明一个变量,该变量将指向可变参数列表
  • va_start 宏:其作用是初始化 va_list 类型的变量,让它指向可变参数列表的第一个参数
void va_start(va_list ap, last);
//ap:va_list 类型的变量
//last:可变参数列表之前的最后一个固定参数
  • va_arg 宏:此宏用于从可变参数列表中获取下一个参数,并将 va_list 指针移动到下一个参数的位置
type va_arg(va_list ap, type);
//ap:va_list 类型的变量
//type:要获取的参数的类型
  • va_end 宏:该宏用于结束对可变参数列表的访问,进行必要的清理工作
void va_end(va_list ap);
//ap:之前用 va_start 初始化过的 va_list 变量

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • crontab执行结果未通过发送mail通知用户的方法

    crontab执行结果未通过发送mail通知用户的方法

    这篇文章主要给大家介绍了关于crontab执行结果未通过发送mail通知用户的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用linux系统具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • Linux网络配置和监控命令总结

    Linux网络配置和监控命令总结

    本文介绍了Linux系统中常用的网络配置和监控命令,包括ifconfig、hostname、route、netstat、ss、lsof、ping、traceroute、nslookup等命令的使用方法和作用,适用于系统管理员在日常管理和故障排查中的网络操作
    2024-09-09
  • Linux使用 iftop 实时监控网卡的流量

    Linux使用 iftop 实时监控网卡的流量

    iftop可以用来监控网卡的实时流量(可以指定网段)、反向解析IP、显示端口信息等。这篇文章主要介绍了Linux 实时网卡流量监控,需要的朋友可以参考下
    2019-11-11
  • Linux新建虚拟机Ubuntu的图文教程

    Linux新建虚拟机Ubuntu的图文教程

    这篇文章主要详细介绍了Linux新建虚拟机Ubuntu的教程,文章通过图文结合的方式给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-09-09
  • Hadoop 2.X新特性回收站功能的讲解

    Hadoop 2.X新特性回收站功能的讲解

    今天小编就为大家分享一篇关于Hadoop 2.X新特性回收站功能的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 11个有用的Linux命令

    11个有用的Linux命令

    Linux命令行吸引了大多数Linux爱好者。一个正常的Linux用户一般掌握大约50-60个命令来处理每日的任务。今天为你解释下面几个命令:sudo、python、mtr、Ctrl+x+e、nl、shuf、shuf、last。
    2013-10-10
  • Linux静态库与动态库实例详解

    Linux静态库与动态库实例详解

    这篇文章主要介绍了 Linux静态库与动态库实例详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2017-10-10
  • Linux上定位后台服务偶发崩溃的解决方法

    Linux上定位后台服务偶发崩溃的解决方法

    在本篇内容中小编给大家整理的是一篇关于Linux上定位后台服务偶发崩溃的解决方法,有需要的朋友们可以学习参考下。
    2020-11-11
  • Linux系列教程之虚拟机中安装Centos7.0

    Linux系列教程之虚拟机中安装Centos7.0

    这篇文章主要为大家详细介绍了Linux系列教程之虚拟机中安装Centos7.0的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • 在Linux中如何查看可用的网络接口详解

    在Linux中如何查看可用的网络接口详解

    这篇文章主要给大家介绍了关于在Linux中如何查看可用的网络接口的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Linux具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03

最新评论