Linux——命名管道

news2024/11/13 13:52:11

Linux——命名管道

  • 命名管道
    • 命名管道和匿名管道的区别
  • 创建命名管道
    • 利用命名管道实现简单通信

我们之前学习了匿名管道,这种管道有一个缺点就是只有两个有血缘关系的进程才能够使用匿名管道,这个非常不方便。所以我们又在匿名管道的基础之上引入了命名管道,它允许两个没有血缘关系的进程进行通信。

如果有小伙伴对匿名管道还不是很了解的话,可以点击这里:

https://blog.csdn.net/qq_67693066/article/details/136371517

命名管道

命名管道(Named Pipes)是一种进程间通信(IPC,Inter-Process Communication)机制,允许在操作系统中的不同进程之间进行可靠的数据传输。它在Unix-like系统(如Linux)和Windows系统中均有实现。
在命名管道中,不同于匿名管道,通信双方不需要有直接的父子进程关系,任何一个进程可以通过管道的名字(即“命名”)来访问管道进行通信,这使得不相关的进程之间也能进行数据交换
命名管道在操作系统中表现为一种特殊类型的文件,它存在于系统的命名空间中,可以像打开文件那样被打开和读写。一旦创建,命名管道就可以在不同的进程中被打开多次,允许单向或双向的数据流传输。
在Windows系统中,命名管道可通过服务器/客户端模式进行通信,一个进程可以作为管道服务器监听并接受连接请求,而其他进程作为管道客户端连接到已命名的管道并进行通信。
在Linux系统中,命名管道也称为FIFO(First-In-First-Out),是文件系统中的一个特殊文件,具有先进先出的特性,通过文件操作接口进行读写。
无论是Windows还是Linux系统,命名管道都支持跨进程甚至是跨计算机(在网络环境下)的通信,为分布式系统中的进程间协作提供了便利。

命名管道和匿名管道的区别

命名管道(Named Pipe)和匿名管道(Anonymous Pipe)在操作系统中都是用于进程间通信(IPC)的重要机制,它们之间的主要区别如下:

  1. 名称和持久性
  • 匿名管道:没有名字,由创建它的进程自动创建并立即可用,生命周期通常与创建它的进程相关联,进程结束时管道消失。
  • 命名管道:有全局唯一的名称,在文件系统中作为一个特殊类型的文件存在,即使创建它的进程终止,只要管道文件未被删除,其他进程依然可以通过名称打开并使用这个管道进行通信。
  1. 范围和用途
  • 匿名管道:主要用于同一台计算机上的具有亲缘关系(通常是父子进程)的进程间通信,不适合跨机器或跨越长时间周期的通信。
  • 命名管道:不仅可用于同一台计算机上的进程间通信,而且支持非亲缘关系进程间的通信,甚至可以在网络环境中的不同计算机之间使用,实现了跨计算机的IPC功能。
  1. 创建和使用方式
  • 匿名管道:由操作系统在创建新进程时自动创建(如fork调用后),或者通过特定API函数(如Unix/Linux中的pipe()函数)手动创建。
  • 命名管道:需要通过系统调用如mkfifo()在文件系统中显式创建,随后其他进程通过文件路径名打开。
  1. 访问权限和安全性
  • 匿名管道:创建后只能由创建它的进程及其后代进程访问,权限控制相对简单。
  • 命名管道:可以设置权限,允许不同用户和组访问,具有更高的安全性,因为它可以根据文件系统权限进行控制。
  1. 方向性
  • 早期的匿名管道在某些实现中可能是单向的,而命名管道通常可以实现双向通信。
  1. 复用性
  • 匿名管道:一般是一对一通信,不能被多个读写进程共享(除了父子进程)。
  • 命名管道:可以被多个读写进程同时打开,实现一对多或多对多的通信。

综上所述,命名管道相比于匿名管道提供了更大的灵活性和扩展性,但也带来了额外的管理和安全性考量。

创建命名管道

在Linux下,我们可以直接敲命令行直接创建命名管道:mkfifo
在这里插入图片描述
比如我想创建一个myfifo的命名管道:
在这里插入图片描述这个时候我们就创建了一个myfifo的命名管道。那么这个命名管道有什么用呢?

利用命名管道实现简单通信

我们可以就利用我们的这个管道实现一个简单的通信,首先我们先创建两个.cc文件:
在这里插入图片描述

我们在client.cc中写下这么一段代码:

#include<iostream>
#include<stdlib.h>
#include<fcntl.h>
#include<cstring>
#include<unistd.h>


int main()
{
    //以写的方式打开管道
    int wfd = open("../myfifo",O_WRONLY);

    if(wfd == -1)
    {
        perror("open fail");
        exit(EXIT_FAILURE);
    }
    else
    {

        while(true)
        {
            //准备输入
            std::string my_information;
            std::cout<<"Please enter:";
            std::getline(std::cin, my_information); // 使用 getline 获取整行输入,包括换行符


            // 移除末尾的换行符
            if (!my_information.empty() && my_information.back() == '\n')
            {
                my_information.pop_back(); // 删除最后一个字符(如果它是换行符)
            }

            size_t length_without_newline = my_information.length();
            if(write(wfd, my_information.c_str(), length_without_newline) == -1)
            {
                perror("write fail");
                exit(EXIT_FAILURE);
            }


            std::cout << "Client say: " << my_information;
            }
    }

    return 0;
    
}

在server.cc中写下:

#include<iostream>
#include<stdlib.h>
#include<fcntl.h>
#include<cstring>
#include<unistd.h>


int main()
{
    //以写的方式打开管道
    int wfd = open("../myfifo",O_WRONLY);

    if(wfd == -1)
    {
        perror("open fail");
        exit(EXIT_FAILURE);
    }
    else
    {

        while(true)
        {
            //准备输入
            std::string my_information;
            std::cout<<"Please enter:"<<std::endl;
            std::getline(std::cin, my_information); // 使用 getline 获取整行输入,包括换行符


            // 移除末尾的换行符
            if (!my_information.empty() && my_information.back() == '\n')
            {
                my_information.pop_back(); // 删除最后一个字符(如果它是换行符)
            }

            size_t length_without_newline = my_information.length();
            if(write(wfd, my_information.c_str(), length_without_newline) == -1)
            {
                perror("write fail");
                exit(EXIT_FAILURE);
            }
            }
    }

    return 0;
    
}

我们打开多个窗口:
在这里插入图片描述
通过命名管道我们实现了两个程序的交流。

我们也可以通过mkfifo函数实现对管道的创建:

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h> // 包含mkfifo函数声明


int main() {
    const char *fifo_name = "/tmp/my_fifo"; // 命名管道的路径
    // 创建命名管道
    if (mkfifo(fifo_name, 0666) == -1) { // 第二个参数是权限模式
        perror("mkfifo");
        exit(EXIT_FAILURE);
    }
    printf("命名管道 '%s' 已成功创建\n", fifo_name);
    return 0;

}

在这段代码中,mkfifo(“/tmp/my_fifo”, 0666)用于在"/tmp"目录下创建一个名为"my_fifo"的命名管道,权限设置为所有用户均可读写(0666)。创建成功后,其他进程可以通过文件路径名打开并使用此命名管道进行通信。

命名管道的知识不是特别多,但是我们可以利用命名管道来创建进程池。这个应该还蛮有意思的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1546355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux实现m4a格式转换为wav格式

需要在linux上安装ffmpeg 参考博客 Linux上安装ffmpeg修改环境变量【这一点很重要&#xff0c;自己因为没有添加环境变量&#xff0c;捣鼓了很长时间】 将ffmpeg的绝对路径添加到 PATH 环境变量中&#xff0c;以让系统能找到ffmpeg的安装路径。 # /home//project/ffmpeg-6.1-a…

QT作业day3

1、使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是…

vue3+threejs新手从零开发卡牌游戏(八):关联卡组和手牌区、添加初始化卡组和初始化手牌逻辑

首先我们优化下之前的代码&#xff0c;先加载游戏资源&#xff0c;然后再初始化场景&#xff0c;由于目前只有一个font字体需要加载&#xff0c;所以我们将之前game/deck/p1.vue中的font相关代码迁移到game/index.vue下&#xff0c;同时使用async和await处理异步加载&#xff0…

干货分享之反射笔记

入门级笔记-反射 一、利用反射破泛型集合二、Student类三、获取构造器的演示和使用1.getConstructors只能获取当前运行时类的被public修饰的构造器2.getDeclaredConstructors:获取运行时类的全部修饰符的构造器3.获取指定的构造器3.1得到空构造器3.2得到两个参数的有参构造器&a…

基于java+springboot+vue实现的超市管理系统(文末源码+Lw+ppt)23-354

摘 要 系统根据现有的管理模块进行开发和扩展&#xff0c;采用面向对象的开发的思想和结构化的开发方法对超市管理的现状进行系统调查。采用结构化的分析设计&#xff0c;该方法要求结合一定的图表&#xff0c;在模块化的基础上进行系统的开发工作。在设计中采用“自下而上”…

启扬RK3568核心板助力智慧步道轻装健身,打造全民健康生活新方式

随着物联网、AI智能等新技术的快速发展&#xff0c;智慧步道成为全国各地公园建设和全民健身公共服务设施改造的新主题。智慧步道基于物联网、人脸识别、大数据分析等技术&#xff0c;对人们的运动进行监测和数据采集&#xff0c;显示运动数据&#xff0c;包括里程统计、热量消…

【王道训练营】第6题 输入一个整型数,判断是否是对称数,如果是,输出yes,否则输出no

文章目录 我的代码改正代码其他代码 我的代码 没有完成 #include<stdio.h> int main(){int a;int b;int c0;//位数int d0;//比较几次scanf("%d",&a);while(b!0){bb/10;c;}dc/2;//比较几次int ffor(int i0 ;i<d;i){int ec;//位数fa - a / (((e-i-1)*10…

2024年软件测试,“我“从初级到高级进阶,不再走弯路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 现在2024年&#…

Python算法100例-4.2 列出真分数序列

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.拓展训练 1&#xff0e;问题描述 按递增顺序依次列出所有分母为40、分子小于40的最简分数。 2&#xff0e;问题分析 分子和分母只有公因数1的分数&…

Maven发布开源框架到远程仓库

1.背景 当你写了一个自我感觉良好的开源工具希望给他人分享&#xff0c;如果只是在github等网站进行公布之外&#xff0c;用户使用起来还不是很方便&#xff0c;特别是当你提供是特定领域的基础工具。你还可以把它部署到中央仓库&#xff0c;这样别人使用就会方便很多。接下来…

android_uiautomator元素定位

通过UIAUTOMATOR的text属性定位到元素&#xff0c;并打印文本from appium import webdriver from appium.webdriver.common.appiumby import AppiumBy import time # For W3C actions from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriv…

Kafka总结问题

Kafka Kafka Kafka Kafka的核心概念/ 结构 topoic Topic 被称为主题&#xff0c;在 kafka 中&#xff0c;使用一个类别属性来划分消息的所属类&#xff0c;划分消息的这个类称为 topic。topic 相当于消息的分配标签&#xff0c;是一个逻辑概念。主题好比是数据库的表&#xff0…

AI视频激光综合驱鸟装置:全自动、大范围驱鸟 | 真驱鸟科技

在电力系统中&#xff0c;鸟害事故已成为一个不容忽视的问题&#xff0c;直接威胁到电网的正常运行。但鸟类拥有极强的环境适应能力&#xff0c;它们能够在各种环境中生存和繁衍。这种强大的适应性使得传统的单一功能驱鸟器&#xff0c;在面对鸟类时显得力不从心&#xff0c;无…

Github简单入门教程

文章目录 使用前提查看项目内容查看项目介绍打包下载项目查看项目作者项目搜索复制项目分支项目创建向项目中添加文件对项目进行评论 使用前提 想要使用Github&#xff0c;首先需要学会科学上网&#xff0c;不然用国内的网在正规情况下是无法访问Github滴~ 查看项目内容 打开…

【Pt】马灯贴图绘制过程 01-制作基础色

目录 一、导入模型并烘焙 二、制作基础底漆 &#xff08;1&#xff09;底漆层 &#xff08;2&#xff09;水痕层 &#xff08;3&#xff09;指纹层 一、导入模型并烘焙 1. 导入模型&#xff0c;马灯模型如下所示 2. 在纹理集设置中点击“烘焙模型贴图” 设置输出大小为…

使用 Amazon Bedrock + Claude 3 打造个性化智能编程助手

最近&#xff0c;随着人工智能技术的迅速发展&#xff0c;代码助手已经成为软件开发领域备受关注的工具。像 Amazon CodeWhisperer 和 Github Copilot 这样的工具可以在集成开发环境中帮助用户自动生成代码&#xff0c;极大地提高了开发效率。然而&#xff0c;这些助手通常缺乏…

HarmonyOS 健康系统联系案例 创建项目

上文 HarmonyOS 健康系统联系案例 整体原型图介绍 我们 介绍了健康系统的整体 UI 然后 我们一点一点来 今天先搭个环境 首先 我们打开开发工具首页 创建项目 一个非常令人怀念的步骤啊 我们点击 Create Project 创建一个新的工程 模板 还是选最基础的 Empty Ability 然后 …

【鸿蒙HarmonyOS开发笔记】使用@Preview装饰器预览组件

概述 ArkTS应用/服务支持组件预览&#xff0c;要求compileSdkVersion为8或以上。组件预览支持实时预览&#xff0c;不支持动态图和动态预览。组件预览通过在组件前添加注解Preview实现&#xff0c;在单个源文件中&#xff0c;最多可以使用10个Preview装饰自定义组件。 Preview…

[C++]函数重载(什么是函数重载,函数重载的原理(底层怎么实现))

一、什么是函数重载 函数重载是指在同一作用域内&#xff0c;可以有多个功能类似具有相同函数名&#xff0c;不同参数列表&#xff08;包括参数类型、参数个数、参数顺序&#xff09;的函数。编译器会根据函数调用时提供的参数来决定调用哪一个具体的函数。 注意&#xff1a;只…

洛谷_P1102 A-B 数对_python写法

P1102 A-B 数对 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 解法一&#xff1a; n, c map(int,input().split())data list(map(int,input().split())) data.sort() maxx max(data)sum 0 l [0 for _ in range(maxx1)] for i in data:l[i] 1 for b in range(1, maxx1)…