Linux操作系统——命名管道

我们前面说的管道都是只能具有血缘关系的进程进行进程间通信,如果我想让两个毫不相干的进程进行通信呢?那就需要来谈谈命名管道了。

命名管道

  • 管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信。
  • 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。
  • 命名管道是一种特殊类型的文件

我们前面说进程通信的本质是让不同的进程看到同一份资源,而如果我们如何让两个毫不相干的进程看到同一份资源呢?因为路径是具有唯一性的,所以,我们可以使用路径+文件名,来唯一的让不同的进程看到同一份资源。

假设有A进程和B进程,A进程要打开一个文件,那么他要为该文件创建对应的struct file,还要创建关于该文件的一些内部对象,比如说inode,缓冲区,方法集等这些东西。然后当我们在同路径下用B进程打开这个文件,操作系统还用不用重新加载该文件的inode ,缓冲区这些东西,然后再打开了呢?答案是不用再打开了,也不用再加载了,因为他已经加载到内存了,操作系统不会做重复的工作,不会将文件的这些内部对象在内存中加载很多份,但是这两个进程一个是读一个是写,要有不同的读写位置,所以要有独立的struct file,这两个struct file都指向同一个缓冲区。所以我们的A进程和B进程指向的是一个共享的区域,所以原理呢其实就是跟之前谈到的匿名管道是一模一样的。我们对应的结论就是,我们之前讲过进程之间是具有独立性的,进程间要完成通信就必须看到同一份资源,而我们这里谈到的同一份资源就是同一个缓冲区,但是管道文件就不用在磁盘上做刷新了,它是一种内存级的,然后又符合单向通信的原则的。那么这里又是通过什么方式让不同的进程看到相同的资源的呢?其实就是我们所说的通过路径+文件名这种做法。

创建一个命名管道

命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

$ mkfifo filename

命名管道也可以从程序里创建,相关函数有:

int mkfifo(const char *filename,mode_t mode);

创建命名管道:

int main(int argc, char *argv[])
{
    mkfifo("p2", 0644);
    return 0;
}

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

  • 匿名管道由pipe函数创建并打开。
  • 命名管道由mkfifo函数创建,打开用open
  • FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完成之后,它们具有相同的语义。

命名管道的打开规则

  • 如果当前打开操作是为读而打开FIFO时
    • O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
    • O_NONBLOCK enable:立刻返回成功
  • 如果当前打开操作是为写而打开FIFO时
    • O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
    • O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

用命名管道实现server&client通信

源代码:

server.cc

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


using namespace std;

bool MakeFifo()
{
    int n = mkfifo(FILENAME,0666);
    if(n<0)
    {
        cerr<<"errno: "<<errno<<", errstring: "<<strerror(errno)<<endl;
        return false;
    }

    cout<<"mkfifo success ...read"<<endl;
    return true;
}

int main()
{
Start:
    int rfd = open(FILENAME,O_RDONLY);
    if(rfd < 0)
    {
        cerr<<"errno: "<<errno<<", errstring: "<<strerror(errno)<<endl;
        if(MakeFifo()) goto Start;
        else return 1;
    }

    cout<<"open fifo success ..."<<endl;
    char buffer[1024];

    while(true)
    {
        ssize_t s = read(rfd,buffer,sizeof(buffer)-1);
        if(s>0)
        {
            buffer[s] = 0;
            cout<<"Client say# "<<buffer<<endl;
        }
        else if(s == 0)
        {
            cout<<"client quit , server quit too!"<<endl;
            break;
        }
    }

    close(rfd);
    cout<<"close fifo success ..."<<endl;
    return 0;
}

client.cc

#include<iostream>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<cerrno>
#include<cstdlib>
#include<cstring>
#include<fcntl.h>
#include"comm.h"
using namespace std;

int main()
{
    int wfd = open(FILENAME,O_WRONLY);
    if(wfd<0)
    {
        cerr<<"errno: "<<errno<<", errstring: "<<strerror(errno)<<endl;
        return 1;
    }
    
    cout<<"mkfifo success ...write"<<endl;
    string message;
    while(true)
    {
        cout<<"Please Enter# ";
        getline(cin,message);

        ssize_t s = write(wfd,message.c_str(),message.size());
        if(s<0)
        {
            cerr<<"errno: "<<errno<<", errstring: "<<strerror(errno)<<endl;
            break;
        }
    }

    close(wfd);
    cout<<"close fifo success ..."<<endl;
    return 0;
}

Makefile:

.PHONY:all
all:server client

client:client.cc
	g++ -o $@ $^ -std=c++11

server:server.cc
	g++ -o $@ $^ -std=c++11

.PHONY:clean
clean:
	rm -f server client .fifo

comm.h

#pragma once


#define FILENAME ".fifo"

运行结果:

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

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

相关文章

软考 系统分析师系列知识点之信息系统战略规划方法(11)

接前一篇文章&#xff1a;软考 系统分析师系列知识点之信息系统战略规划方法&#xff08;10&#xff09; 所属章节&#xff1a; 第7章. 企业信息化战略与实施 第4节. 信息系统战略规划方法 7.4.7 价值链分析法 价值链分析&#xff08;Value Chain Analysis&#xff0c;VCA&am…

【C++】---类和对象(中)默认成员函数 和 操作符重载

前言&#xff1a; 假如一个类中既没有成员变量也没有成员函数&#xff0c;那么这个类就是空类&#xff0c;空类并不是什么都没有&#xff0c;因为所有类都会生成如下6个默认成员函数&#xff1a; 一、构造函数 1、构造函数的定义及其特性 对于日期类对象&#xff0c;我们可…

pytest教程-10-allue2生成html报告

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest-html生成html报告的方法&#xff0c;本小节我们讲解一下使用allue2生成html报告。 自动化测试执行完成后我们需要展示给其他人看&#xff0c;这就要有自动化测试报告了。复杂的测试报告…

稳态准直太阳光模拟器

概述 稳态准直太阳光模拟器是一种用于模拟太阳光的设备。它能够产生高强度、高稳定性的太阳光&#xff0c;用于太阳能电池、太阳能热利用等领域的研究和实验。 稳态准直太阳光模拟器通常由以下几个部分组成&#xff1a; 光源&#xff1a;采用强度和颜色温度与太阳光接近的光源…

Rust 语言学习杂谈 (end) (各种工作中遇到的疑难杂症)

1.在运行 “cargo build --release” 的时候&#xff0c;到底发生了什么&#xff1f; 源 (GPT4.0) : 当我们运行 cargo build --release 命令时&#xff0c;实际上在进行一系列复杂的步骤来编译和构建 Rust 项目的发布版本。这个过程大致可以分解为以下几个步骤&#xff1a;…

2024年【危险化学品经营单位安全管理人员】考试报名及危险化学品经营单位安全管理人员考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员考试报名是安全生产模拟考试一点通总题库中生成的一套危险化学品经营单位安全管理人员考试资料&#xff0c;安全生产模拟考试一点通上危险化学品经营单位安全管理人员作业手机同步练习…

基于GPT一键完成数据分析全流程的AI Agent: Streamline Analyst

大型语言模型&#xff08;LLM&#xff09;的兴起不仅为获取知识和解决问题开辟了新的可能性&#xff0c;而且催生了一些新型智能系统&#xff0c;例如旨在辅助用户完成特定任务的AI Copilot以及旨在自动化和自主执行复杂任务的AI Agent&#xff0c;使得编程、创作等任务变得高效…

单片机学习笔记---直流电机驱动(PWM)

直流电机介绍 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极&#xff0c;当电极正接时&#xff0c;电机正转&#xff0c;当电极反接时&#xff0c;电机反转 直流电机主要由永磁体&#xff08;定子&#xff09;、线圈&#xff08;转子&#xff09;和换向器…

正向代理和反向代理

文章目录 概述正向代理反向代理主要用途 概述 正向代理和反向代理都是网络中常见的代理类型&#xff0c;用于在客户端和服务器之间进行通信。 正向代理&#xff08;Forward Proxy&#xff09;是位于客户端和目标服务器之间的代理服务器。当客户端发送请求时&#xff0c;请求会…

批量梯度下降、随机梯度下降、小批量梯度下降

一、批量梯度下降&#xff08;Batch Gradient Descent,BGD&#xff09; 在批量梯度下降中&#xff0c;每次迭代都使用整个训练集的数据进行梯度计算和参数更新。也就是说&#xff0c;每次迭代都对所有的样本求取梯度&#xff0c;然后更新参数。由于要处理整个训练集&#xff0c…

算法沉淀——优先级队列(堆)(leetcode真题剖析)

算法沉淀——优先级队列 01.最后一块石头的重量02.数据流中的第 K 大元素03.前K个高频单词04.数据流的中位数 优先队列&#xff08;Priority Queue&#xff09;是一种抽象数据类型&#xff0c;它类似于队列&#xff08;Queue&#xff09;&#xff0c;但是每个元素都有一个关联的…

WEB APIs(2)

应用定时器可以写一个定时轮播图&#xff0c;如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport&qu…

如何在电脑和 SD 卡上恢复已删除 MOV等视频文件

MOV 是 Apple 创建的多媒体容器。您可能已经意识到&#xff0c;用 macOS QuickTime Player 录制的视频是以 MOV 格式保存的&#xff0c;而且 MOV 在 Windows 上也兼容。我们可能已经保存了很多 MOV 格式的视频。但是&#xff0c;如果这些 MOV 文件丢失或被意外删除怎么办&#…

Python二级考试笔记

Python二级考试笔记【源源老师】 01. 字符串 1. 常规功能合集 字符串本身有一些功能&#xff0c;有些之前运用过&#xff0c;这里总结如下&#xff1a; # 功能一&#xff1a;判断字符串类型 print(type("Hello")) print(str(123)) # 转换# 功能二&#xff1a;连…

OpenCV Mat实例详解 一

OpenCV中的Mat是一个类&#xff0c;它用存储图像信息。由两部分数据组成&#xff1a;矩阵头和像素值矩阵。矩阵头包含矩阵尺寸、存储方法、存储地址等信息&#xff0c;而像素值矩阵则存储实际的像素值数据。 Mat类在OpenCV中有十分重要的作用&#xff0c;图像信息的载入、保存、…

【知识图谱--第三讲知识图谱的存储与查询】

知识图谱的存储与查询 基于关系型数据库的知识图谱存储基于原生图数据库的知识图谱存储原生图数据库实现原理浅析 基于关系型数据库的知识图谱存储 基于原生图数据库的知识图谱存储 原生图数据库实现原理浅析

每日一题——LeetCode1437.是否所有1都至少相隔k个元素

方法一 两次遍历&#xff1a; 第一次遍历保存所有1的位置到res里&#xff0c;第二次遍历res检查是否所有相邻元素之间间隔都>k var kLengthApart function(nums, k) {let res[]for(let i0;i<nums.length;i){if(nums[i]1){res.push(i)}}for(let i1;i<res.length;i){…

Python 中实现线性搜索算法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 线性搜索算法&#xff0c;也称为顺序搜索算法&#xff0c;是一种简单但常用的搜索技术&#xff0c;用于查…

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程

VMwareWorkstation17.0虚拟机安装Windows2.03完整详细步骤图文教程 第一篇 下载Windows2.03第二篇 配置Windows2.03虚拟机机器环境第三篇 启动Windows2.03系统 第一篇 下载Windows2.03 1.Windows2.0原版软盘下载地址是 暂不提供&#xff0c;后续更新 2.Windows2.03虚拟机镜像下…

P1228 地毯填补问题题解

题目 相传在一个古老的阿拉伯国家里&#xff0c;有一座宫殿。宫殿里有个四四方方的格子迷宫&#xff0c;国王选择驸马的方法非常特殊&#xff0c;也非常简单&#xff1a;公主就站在其中一个方格子上&#xff0c;只要谁能用地毯将除公主站立的地方外的所有地方盖上&#xff0c;…