Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Linux】命名管道

【Linux】命名管道

作者头像
s-little-monster
发布于 2025-03-04 00:52:46
发布于 2025-03-04 00:52:46
54400
代码可运行
举报
运行总次数:0
代码可运行

一、命名管道

1、与匿名管道的关系

命名管道由mkfifo创建,是一个文件,打开要用open打开 命名管道与匿名管道之间唯一的区别就是它们创建和打开的方式不同,其他基本上相同 命名管道也只能和有“血缘”的进程进行通信

2、工作原理

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

可以看到它的第一列为p,说明它是特殊文件 在我们对普通文件进行打开的时候,我们要进行的结构其实是这样的

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

3、系统调用接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *filename, mode_t mode);
// filename:文件路径
// mode:文件权限
// 返回值:如果管道创建成功返回0,如果失败返回-1并设置errno

4、实现两个进程间通信

tests.c
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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.hva_list :va_list 是一种自定义类型(通常为指针类型),用于声明一个变量,该变量将指向可变参数列表

va_start 宏:其作用是初始化 va_list 类型的变量,让它指向可变参数列表的第一个参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void va_start(va_list ap, last);
//ap:va_list 类型的变量
//last:可变参数列表之前的最后一个固定参数

va_arg 宏:此宏用于从可变参数列表中获取下一个参数,并将 va_list 指针移动到下一个参数的位置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type va_arg(va_list ap, type);
//ap:va_list 类型的变量
//type:要获取的参数的类型

va_end 宏:该宏用于结束对可变参数列表的访问,进行必要的清理工作

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void va_end(va_list ap);
//ap:之前用 va_start 初始化过的 va_list 变量

今日分享就到这里~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
命名管道Linux
首先自己要用用户层缓冲区,还得把用户层缓冲区拷贝到管道里,(从键盘里输入数据到用户层缓冲区里面),然后用户层缓冲区通过系统调用(write)写到管道里,然后再通过read系统调用,被对方(读端)读取,就要从管道拷贝到读端,然后再显示到显示器上。
ljw695
2024/10/18
6140
命名管道Linux
【Linux】日志插件
故障排查与问题定位 快速发现问题:日志能够实时记录系统运行过程中的各种事件和状态信息,当系统出现故障或异常时,通过查看日志可以快速察觉到问题的发生,例如,服务器突然崩溃,日志中可能会记录下崩溃前的错误信息、异常堆栈,帮助运维人员第一时间得知系统出现了故障
s-little-monster
2025/03/11
4930
【Linux】日志插件
初识Linux · 命名管道
有了前文匿名管道的基础,我们介绍匿名管道的时候就轻松许多了,匿名管道和命名管道的区别主要是在于,匿名管道不需要文件路径,并且匿名管道常用于父子进程这种具有血缘关系的场景,使用命名管道的时候,我们常常用于的情况是两个进程毫无联系,使这两个毫无关系的进程可以进行通信。
_lazy
2024/11/19
4070
初识Linux · 命名管道
匿名管道和命名管道
https://blog.csdn.net/2401_83427936/article/details/142603367
ljw695
2024/10/18
3600
匿名管道和命名管道
【Linux】基于管道进行进程间通信
进程间通信是两个或者多个进程实现数据层面的交换。但是由于进程间存在独立性,所以导致进程间通信的成本比较高。
YoungMLet
2024/03/01
3050
【Linux】基于管道进行进程间通信
【Linux】 管道扩展 — 开始使用命名管道
命名管道时进程间通信的一种,那么原理也就是类似的:先让不同的进程看到同一份(操作系统)资源(“一段内存”)。
叫我龙翔
2024/05/31
3990
【Linux】 管道扩展 — 开始使用命名管道
C语言函数大全--v 开头的函数
huazie
2025/07/22
1440
C语言函数大全--v 开头的函数
【Linux】日志函数
日志在程序设计中扮演着至关重要的角色,它不仅是程序运行情况的记录者,还是问题诊断、性能优化、安全审计以及用户行为分析的重要工具。本篇博客我们就设计一个日志函数,并在过程中学习一些知识。
破晓的历程
2024/08/29
3350
【Linux】深度探秘命名管道:Linux 进程通信的无声桥梁
文章链接:https://cloud.tencent.com/developer/article/2466294
Yui_
2024/11/18
3080
【Linux】深度探秘命名管道:Linux 进程通信的无声桥梁
【Linux篇】轻松搭建命名管道通信:客户端与服务器的互动无缝连接
命名管道(Named Pipe)是一种用于进程间通信(IPC)的机制,它允许不同进程之间通过一个命名的通道交换数据。与匿名管道不同,命名管道是通过一个系统级的文件路径来标识和访问,允许不同的进程在不同的时间、甚至不同的机器上进行通信。
熬夜学编程的小王
2025/04/22
2070
【Linux篇】轻松搭建命名管道通信:客户端与服务器的互动无缝连接
日志代码编写
  日志是程序周期性运转或者特定时刻等一些常规或者特殊消息以特殊的形式打印出来,我们称为日志,关于日志,AI是这样回答的:
用户11029129
2024/11/02
2660
日志代码编写
【Linux】IPC 进程间通信(一):管道(匿名管道&命名管道)
为了实现两个或者多个进程实现数据层面的交互,因为进程独立性的存在,导致进程通信的成本比较高
IsLand1314
2024/11/19
7100
【Linux】IPC 进程间通信(一):管道(匿名管道&命名管道)
【Linux】管道通信——命名管道
命名管道,也称为 FIFO(First In First Out),是一种 进程间通信(IPC) 机制,它允许不相关的进程(即没有父子关系的进程)通过文件系统中的特殊文件进行数据传输。
用户11305458
2025/02/25
7120
【Linux】管道通信——命名管道
【Linux进程#1】IPC 进程间通信(一):管道(匿名管道&命名管道)
✨ 无人扶我青云志,我自踏雪至山巅 🌏
IsLand1314
2025/06/02
2280
【Linux进程#1】IPC 进程间通信(一):管道(匿名管道&命名管道)
进程间通信Linux
首先自己要用用户层缓冲区,还得把用户层缓冲区拷贝到管道里,(从键盘里输入数据到用户层缓冲区里面),然后用户层缓冲区通过系统调用(write)写到管道里,然后再通过read系统调用,被对方(读端)读取,就要从管道拷贝到读端,然后再显示到显示器上。
ljw695
2024/11/15
5320
进程间通信Linux
【Linux】进程间通信:命名管道
管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道
用户11029103
2025/03/14
2090
【Linux】进程间通信:命名管道
Linux进程通信之管道解析
管道是 UNIX系统 IPC的最古老的形式,所有的UNIX系统都提供此种通信。所谓的管道,也就是内核里面的一串缓存,从管道的一段写入的数据,实际上是缓存在内核中的,令一端读取,也就是从内核中读取这段数据。对于管道传输的数据是无格式的流且大小受限。对于管道来说,也分为匿名管道和命名管道,其中命名管道也被叫做 FIFO,下面则分别阐述这两种管道。
wenzid
2021/07/20
1.5K0
Linux进程通信之管道解析
初识Linux · 日志编写
在线程池部分我们纵观全文,可以发现全文有很多很多的IO流,看起来还是差点意思的,而我们今天提到的日志,是在今后的代码编写中会经常接触,或者说在这之前,我们也接触过日志,不过我们没有注意而已,比如平常常用的电脑,强制关机什么的都会在日志里面。
_lazy
2024/12/20
2640
初识Linux · 日志编写
《不定参数与不定宏参数:C++程序员必须掌握的灵活编程技巧》
在 C++ 中,不定参数函数(Variadic Functions) 是一种可以接受数量不确定的参数的函数。这种机制常用于像 printf 这样的标准库函数,也广泛应用于日志系统、格式化输出、通用容器构造等场景
IsLand1314
2025/05/01
2110
Linux进程间通信【命名管道】
命名管道通信属于 IPC 的其中一种方式,作为管道家族,命名管道的特点就是 自带同步与互斥机制、数据单向流通,与匿名管道不同的是:命名管道有自己的名字,因此可以被没有血缘关系的进程看到,意味着命名管道可以实现毫不相干的两个独立进程间通信
北 海
2023/07/01
7200
Linux进程间通信【命名管道】
相关推荐
命名管道Linux
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验