【Linux】命名管道

阿敏酱_3919

阿敏酱_3919

2025-04-18

546人浏览

原创

一、命名管道

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</sys></sys>

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;
}</errno.h></fcntl.h></sys></sys></unistd.h></string.h></stdlib.h></stdio.h>

testr.c

Obsidian (Linux)
Obsidian (Linux)

操作 Obsidian 库(纯 Markdown 笔记),并通过 notesmd-cli 实现自动化。

下载
#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;
}</fcntl.h></sys></sys></unistd.h></string.h></stdlib.h></stdio.h>

二、可变参数列表

我们将利用命名管道编写日志文件,这需要使用可变参数列表的知识,下面详细解释一下。

可变参数列表允许函数接受不确定数量和类型的参数,通常放在参数列表的最后。例如,我们之前在进程中断中的函数: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 变量

今日分享就到这里~

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

include linux c#

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

2023.09.22

549

3

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

2024.03.01

1698

6

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2318

7

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

6859

3

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.08.29

3305

6

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

2025.08.29

4288

10

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2025.08.29

2925

10

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

379

31

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3188

3

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP基础入门课程
PHP基础入门课程

共33课时 | 3.5万人学习

Go语言教程手册
Go语言教程手册

共23课时 | 27.1万人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习