进程间通信之利用命名管道进行通信

文章目录

  • 什么是命名管道
  • 命名管道的作用有什么
  • 命名管道的特点和用法是什么
  • 命名管道与匿名管道有什么区别
    • 匿名管道相较于命名管道的局限性
  • 命名管道如何使用
  • 代码

什么是命名管道

命名管道(Named Pipe),也被称为FIFO(First In, First Out),是一种在Unix和Unix-like操作系统中用于进程间通信的特殊文件类型。它允许不相关的进程通过文件系统中的路径名进行通信。

命名管道的作用有什么

命名管道(Named Pipe)是一种在Unix和Unix-like系统中用于进程间通信的特殊文件类型。它的作用主要体现在以下几个方面:

进程间通信: 命名管道提供了一种进程间通信的方式。不同的进程可以通过共享同一个命名管道文件进行通信,其中一个进程将数据写入管道,而另一个进程从管道中读取数据。这样,进程之间可以实现数据的交换和共享。

无关进程通信: 与匿名管道不同,命名管道可以用于无关的进程之间通信。因为命名管道在文件系统中有一个路径名,进程可以通过路径名来打开和访问它,而不需要共享相同的地址空间或具有亲缘关系。

独立于进程生命周期: 命名管道是持久的,它存在于文件系统中,不受创建它的进程的生命周期限制。这意味着即使创建命名管道的进程结束,其他进程仍然可以使用相同的管道进行通信。

阻塞式通信: 命名管道是阻塞的,即写入端会等待读取端准备好接收数据,反之亦然。这样可以协调进程之间的通信,确保数据的正确传输。

常用于Shell编程: 在Shell编程中,命名管道常用于将一个命令的输出传递给另一个命令,实现管道传输的同时也可以用于进程间通信。

总体而言,命名管道提供了一种方便、灵活且持久的进程间通信机制,适用于各种需要数据交换的场景。

命名管道的特点和用法是什么

文件系统中的路径名: 命名管道在文件系统中有一个路径名,类似于普通文件。进程可以通过打开这个路径名的方式来访问命名管道。

独立的进程通信: 不同进程可以通过共享同一个命名管道文件来进行通信。这使得命名管道成为不同进程之间进行进程间通信的有效手段。

创建和删除: 命名管道可以使用 mkfifo 函数来创建。创建后,它就成为文件系统中的一个特殊文件。当通信结束时,可以使用 unlink 函数删除命名管道。

读写操作: 进程可以像普通文件一样使用文件描述符对命名管道进行读取和写入操作,实现进程间的数据传输

命名管道与匿名管道有什么区别

命名管道(Named Pipe)和匿名管道(Anonymous Pipe)是两种不同类型的管道,它们在创建、使用和生命周期等方面有一些关键区别。

命名管道:

创建: 命名管道在文件系统中有一个路径名,可以通过 mkfifo 函数创建。它是一个具有持久性的文件,不依赖于创建它的进程的生命周期。
路径名: 命名管道有一个在文件系统中的路径名,因此可以被不同的进程通过路径名来访问。
无关进程通信: 不相关的进程可以通过共享同一个路径名的命名管道进行通信。
使用: 通过文件描述符进行读写操作,可以使用标准的文件I/O函数。
生命周期: 命名管道存在于文件系统中,直到显式删除。
匿名管道:

创建: 匿名管道是由 pipe 系统调用创建的,没有在文件系统中的路径名。它是一种临时的、仅存在于相关进程之间的通信机制。
路径名: 不存在路径名,只能在创建它的进程及其相关子进程之间使用。
有关进程通信: 主要用于有关系(亲缘关系)的父子进程之间通信。
使用: 通过文件描述符进行读写操作,可以使用标准的文件I/O函数。
生命周期: 随着创建它的进程或相关子进程的终止而结束。
综上所述,主要区别在于命名管道是具有路径名的、持久的文件,可以被不相关的进程使用;而匿名管道是临时的、只存在于相关进程之间的通信机制,主要用于父子进程之间通信。选择使用哪种管道取决于具体的应用场景和需求。

匿名管道相较于命名管道的局限性

首先我们可以先看一下匿名管道的代码

#include <iostream>
#include <string>
#include <unistd.h>
#include <string.h>
#include <string>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
#define N 2
const int NUM = 1024;
void Write(int n)
{
  string s = "hello,I am chile";
  pid_t self = getpid();
  char buffer[NUM]; // 缓冲区
  int number = 0;
  while (true)
  {
    buffer[0] = 0; // 字符串清空
    snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++);
    // cout << buffer << endl;
    write(n, buffer, strlen(buffer));
    sleep(1);
  }
}
void Read(int rfd)
{
  char buffer[NUM];

  while (true)
  {
    buffer[0] = 0;
    ssize_t n = read(rfd, buffer, sizeof(buffer));
    if (n > 0)
    {
      buffer[n] = 0;
      cout << "father get a message[" << getpid() << "]# " << buffer << endl;
    }
  }
}

int main()
{
  int pipefd[N] = {0};
  int n = pipe(pipefd);
  if (n < 0)
    return 1;
  pid_t id = fork();
  if (id < 0)
    return 2;
  if (id == 0)
  {
    close(pipefd[0]);

    Write(pipefd[1]);

    close(pipefd[1]);
    exit(0);
  }
  close(pipefd[1]);

  Read(pipefd[0]);
  pid_t rid = waitpid(id, NULL, 0);
  if (rid < 0)
  {
    return 3;
  }
  close(pipefd[0]);

  return 0;
}

从上面代码我们可以清晰的感知到匿名管道只适用与具有亲缘关系的进程之间的通信但是我们在实际开发环境中更多的进程是不具备亲缘关系的因此匿名管道就非常的局限了。我们看一下匿名管道的最终实现的效果图
在这里插入图片描述

命名管道如何使用

我们来看一下命名管道的使用效果图
在这里插入图片描述
在这张图我们可以清楚的看到右边输入左边输出达到了我们想要的无亲缘关系的进程的通信

代码

1.comm.hpp文件

#pragma once

#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_FILE "./myfifo"
#define MODE 0664
enum
{
    FIFO_CREATE_ERR = 1,
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
};

class Init
{
public:
    Init()
    {
        int n = mkfifo(FIFO_FILE, MODE);
        if (n == -1)
        {
            perror("mkfifo");
            exit(FIFO_CREATE_ERR);
        }
    }
    ~Init()
    {
        int m = unlink(FIFO_FILE);
        if (m == -1)
        {
            perror("unlink");
            exit(FIFO_DELETE_ERR);
        }
    }
};
  1. server.cpp文件代码
#include "comm.hpp"
#include <iostream>
using namespace std;
int main()
{
    Init init;
    int fd = open(FIFO_FILE, O_RDONLY);
    if (fd < 0)
    {
        exit(FIFO_OPEN_ERR);
    }
    while (true)
    {
        char buffer[1024];
        int len = read(fd, buffer, sizeof(buffer));
        if (len < 0)
        {
            break;
        }
        else if (len > 0)
        {
            buffer[len] = 0;
            cout << "client say#" << buffer << endl;
        }
        else if (len == 0)
        {
            break;
        }
    }
    close(fd);
    return 0;
}
  1. client.cpp的代码
#include "comm.hpp"
#include <iostream>
using namespace std;
int main()
{
    int fd = open(FIFO_FILE, O_WRONLY);
    if (fd == -1)
    {
        perror("open");
        exit(FIFO_OPEN_ERR);
    }
    else
    {
        cout << "client open file done" << endl;
        while (1)
        {
            cout << "Please Enter@ ";
            string a;
            getline(cin, a);
            write(fd, a.c_str(), a.size());
        }
        }
    close(fd);
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通过manifest清单导入项目到gitlab中

文章目录 说明使用manifest得要求Manifest 格式演示示例 说明 从gitlab 11.2引入此功能。 GitLab 允许根据manifest清单文件&#xff08;如 Android 存储库使用的清单文件&#xff09;导入所需的 Git 存储库。 使用manifest得要求 GitLab 必须对其数据库使用 PostgreSQL。至少…

RNN:Recurrent Neural Network(上)

目录 1 为什么提出 RNN 1.1 什么是 Slot Filling 1.2 为什么 FFN 做不好 Slot Filling 1.3 为什么 RNN 能做好 Slot Filling 2 RNN 的整体结构 3 更高级的 RNN 结构 3.1 Deep RNN 3.2 Elman Network & Jordan Network 3.3 Bidirectional RNN 原视频&…

Blender——将模型及其所有纹理与材质导入unity

前期准备 参考视频&#xff1a;7分钟教会你如何将Blender的模型材质导入unity_哔哩哔哩_bilibili 实验模型官网下载地址&#xff1a;Hoi An Ancient House Model free VR / AR / low-poly 3D model CSDN下载链接&#xff1a; 【免费】Blender三维模型-古代房屋模型&#xff…

Ceph分布式存储部署

目录 一、存储 1、存储基础 2、NAS&#xff08;网络附加存储&#xff0c;是通过网络附加到当前主机文件系统之上的存储&#xff09; 3、SAN&#xff08;存储区域网络&#xff09; 4、单机存储的问题 5、商业存储解决方案 6、分布式存储&#xff08;软件定义的存储 SDS&a…

【Redis】更改redis中的value值

今天继续进步一点点~~ 背景&#xff1a;今天有个前端的同事问我&#xff0c;能不能在Redis中他本人登录公众号的 sessionID 加上一列openID 于是我上网查了一堆在Redis里面的命令&#xff0c;以及不同的客户端怎么输入命令&#xff0c;但是后来问了下同事&#xff0c;他就给我…

2024-01-16(SpringCloudMybati)

1.前后端分离&#xff1a;前后端分离开发的理解以及和前后端不分离的区别_前后端交互和前后端分离的区别-CSDN博客 2.resultMap是用于sql语句得到的结果集与实体类之间进行关系映射的。 要求&#xff1a;结果集中的列名和实体类的中属性名要一一对应&#xff0c;并且个数保持…

Linux Shell脚本入门

目录 介绍 编写格式与执行方式 Shell脚本文件编写规范 脚本文件后缀名规范 首行格式规范 注释格式 shell脚本HelloWord入门案例 需求 效果 实现步骤 脚本文件的常用执行三种方式 介绍 3种方式的区别 小结 多命令处理 Shell变量 环境变量 目标 Shell变量的介绍 变量类型 系统环境…

Java:token自动续期,使用Gateway过滤器—GlobalFilter

文章目录 前言一、使用步骤1.实体user2.登录AuthController3.网关GatewayFilter4.续约TokenService 总结 前言 在系统中&#xff0c;在 token 的有效期内&#xff0c;可以登录使用&#xff0c;并且要求如果一直使用系统&#xff0c;一直保持登录状态&#xff0c;而不是 token …

MySQL存储函数与存储过程习题

创建表并插入数据&#xff1a; 字段名 数据类型 主键 外键 非空 唯一 自增 id INT 是 否 是 是 否 name VARCHAR(50) 否 否 是 否 否 glass VARCHAR(50) 否 否 是 否 否 ​ ​ sch 表内容 id name glass 1 xiaommg glass 1 2 xiaojun glass 2 1、创建一个可以统计表格内记录…

pytest文档35-Hooks函数之统计测试结果(pytest_terminal_summary)

前言 用例执行完成后&#xff0c;我们希望能获取到执行的结果&#xff0c;这样方便我们快速统计用例的执行情况。 也可以把获取到的结果当成总结报告&#xff0c;发邮件的时候可以先统计测试结果&#xff0c;再加上html的报告。 pytest_terminal_summary 关于TerminalReport…

Kubernetes(K8S)拉取本地镜像部署Pod 实现类似函数/微服务功能(可设置参数并实时调用)

以两数相加求和为例&#xff0c;在kubernetes集群拉取本地的镜像&#xff0c;实现如下效果&#xff1a; 1.实现两数相加求和 2.可以通过curl实时调用&#xff0c;参数以GET方式提供&#xff0c;并得到结果。&#xff08;类似调用函数&#xff09; 一、实现思路 需要准备如下的…

绑定class,条件渲染,列表过滤,列表排序

目录​​​​​​​ 绑定class 条件渲染 列表过滤 列表排序 绑定class <div class"normal" :class"mood" click"changename">111{{name}}</div><div class"normal" :class"arr">111{{name}}</div…

AI嵌入式K210项目(15)-安全散列算法加速器

文章目录 前言一、什么是SHA256&#xff1f;实验原理 二、K210的安全散列算法加速器三、实验过程总结 前言 K210内置了丰富的加速器&#xff0c;包括神经网络处理器 (KPU)&#xff0c;AES(高级加密加速器)&#xff0c;APU 麦克风阵列语音数据加速计算处理器&#xff0c;现场可…

计算机网络-ACL访问控制列表

上一篇介绍NAT时候就看到了ACL这个东西了&#xff0c;这个是什么意思&#xff1f;有什么作用呢&#xff1f; 一、ACL访问控制列表 访问控制列表 (ACL, Access Control List)是由一系列permit或deny语句组成的、有序规则的列表。ACL是一个匹配工具&#xff0c;能够对报文进行匹配…

前端学习路线图和一些经验

关于前端目前个人建议的一个路线,也是自己之前前端学习时候的一个大致路线,给想要学习前端的小白一个参考,以前自己刚开始接触前端的时候就是不知道该按照什么路线学习 eg-前端是做什么的&#xff1f; 就是开发网站,移动端&#xff0c;小程序之类的页面 调调接口完成页面的渲…

异步非阻塞事件驱动架构的具体流程解析

异步非阻塞事件驱动架构是一种高效的编程和系统设计模式&#xff0c;特别适用于需要处理大量并发连接和请求的应用&#xff0c;如Web服务器。 1. 初始化和启动 启动过程&#xff1a;当Nginx启动时&#xff0c;它的主进程初始化配置并启动多个工作进程。工作进程创建&#xff1…

虚拟线程探索与实践

优质博文&#xff1a;IT-BLOG-CN 一、简介 虚拟线程是轻量级线程&#xff0c;极大地减少了编写、维护和观察高吞吐量并发应用的工作量。虚拟线程是由JEP 425提出的预览功能&#xff0c;并在JDK 19中发布&#xff0c;JDK 21中最终确定虚拟线程&#xff0c;以下是根据开发者反馈…

杂记 | 在Linux上使用Docker-compose安装单机版Milvus向量数据库并配置访问控制和可视化面板(Attu)

文章目录 01 Milvus向量数据库简介02 安装前的准备03 安装3.1 创建milvus工作目录3.2 下载并编辑docker-compose.yml3.3 下载milvus.yml文件3.4 启动milvus 04 访问可视化面板并修改密码 01 Milvus向量数据库简介 Milvus是一款开源的向量数据库&#xff0c;它专为AI应用设计&a…

移动端 h5-table react版本支持虚拟列表

介绍 适用于 react ts 的 h5 移动端项目 table 组件 github 链接 &#xff1a;https://github.com/duKD/react-h5-table 有帮助的话 给个小星星 有两种表格组件 常规的&#xff1a; 支持 左侧固定 滑动 每行点击回调 支持 指定列排序 支持滚动加载更多 效果和之前写的vue…

聚类模型评估指标

聚类模型评估指标-轮廓系数 计算样本i到同簇其它样本到平均距离ai&#xff0c;ai越小&#xff0c;说明样本i越应该被聚类到该簇&#xff08;将ai称为样本i到簇内不相似度&#xff09;&#xff1b;计算样本i到其它某簇Cj的所有样本的平均距离bij&#xff0c;称为样本i与簇Cj的…