Linux命名管道方式

2025-03-20 13:50
文章标签 linux 管道 命名 方式

本文主要是介绍Linux命名管道方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Linux命名管道方式》:本文主要介绍Linux命名管道方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教...

一、命名管道

1、与匿名管道的关系

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

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

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

2、工作原理

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

Linux命名管道方式

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

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

Linux命名管道方式

其中这个刷盘的过程就是文件缓冲区中的数据刷新到硬盘上的过程,而我们的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);
        messawww.chinasem.cnge[strcspn(message, "\n")] = 0; // 移除换行符

        // 向命名管道写入消息
        if (write(fd, message, strlen(message)) == -1)
        {
            perror("write");
            clChina编程ose(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 mpythonain()
{
    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 (ueVHRxtnlink(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 宏:此宏用于从可变参数列表中获取下一python个参数,并将 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 变量

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程China编程(www.chinasem.cn)。

这篇关于Linux命名管道方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153846

相关文章

Spring中配置ContextLoaderListener方式

《Spring中配置ContextLoaderListener方式》:本文主要介绍Spring中配置ContextLoaderListener方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录Spring中配置ContextLoaderLishttp://www.chinasem.cntene

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定