首页 > 运维 > linux运维 > 正文

【Linux】命名管道

看不見的法師
发布: 2025-04-18 13:30:20
原创
535人浏览过

一、命名管道

1、与匿名管道的关系

命名管道通过mkfifo命令创建,是一个文件,需要使用open函数来打开。命名管道与匿名管道的主要区别在于它们的创建和打开方式不同,其他方面基本相同。命名管道也仅能与有“血缘”关系的进程进行通信。

2、工作原理

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

【Linux】命名管道

可以看到文件的第一列为p,表示它是特殊文件。在打开普通文件时,操作流程包括文件缓冲区中的数据刷新到硬盘的过程。然而,命名管道文件不涉及刷盘操作,数据仅停留在文件缓冲区中。由于在Linux中,多个进程打开同一个文件会共享同一个文件缓冲区,因此如果有另一个进程以读的方式打开命名管道文件,它们将通过文件缓冲区建立连接,形成与匿名管道相同的结构。

【Linux】命名管道

3、系统调用接口

#include <sys>
#include <sys>
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>
#include <sys>
#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

NameGPT名称生成器
NameGPT名称生成器

免费AI公司名称生成器,AI在线生成企业名称,注册公司名称起名大全。

NameGPT名称生成器 0
查看详情 NameGPT名称生成器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys>
#include <sys>
#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_listva_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 变量
登录后复制

今日分享就到这里~

以上就是【Linux】命名管道的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号