Linux---命名管道与共享内存(一)

一、命名管道的本质

命名管道必须在磁盘中存在,是一个真实的文件,这是一种特殊的文件,管道文件。

命名管道(FIFO)在文件系统中表现为一个特殊的管道文件(类型为 p ,它有自己的路径和文件名,看起来像 "存在于磁盘上",但实际并不占用磁盘存储空间 ,数据是存储在内核缓冲区里的,只是通过文件系统的路径来标识和访问。

有了inode那么这个文件一定会具有名字。

如何保证打开的是同一个文件?

  1. 在 Linux/Unix 系统中,每个文件都有一个唯一的 inode 号(索引节点),它是文件在文件系统中的唯一标识。

  2. 只要多个进程访问同一个路径 + 文件名,就会定位到同一个 inode,从而保证打开的是同一个命名管道文件。

    • 这也是命名管道能让无亲缘关系的进程互相通信的关键 ------ 通过共享的路径名找到同一个管道。

创建命名管道mkfifo

在文件系统里创建一个命名管道文件,用于进程间通信。

命名管道的属性:

不在磁盘里所以不占空间所以大小为0.

接下来我们进行编写代码:

代码如下:

cpp 复制代码
//client.cc
#include<iostream>
#include"Pipe.hpp"
//向命名管道写

int main()
{
    Fifo fileclient;
    fileclient.open(ForWrite);

    while(true)
    {
        std::cout<<"Please Enter@ "; 
        std::string msg;
        std::fetline(std::cin,msg);
        fileclient.Send(msg);
    }
    
    
}
cpp 复制代码
//server.cc
//向命名管道读
#include"Pipe.hpp"
int main()
{
    Fifo pipefile;
    pipefile.Build();
    pipeile.Open(ForRead);
    std::string msg;


    while(true)
    {

        pipefile.Recv(&msg);
        if (n>0)
        {
            std::cout<<"Client Say# "<<msg<<std::endl;
        }
        else 
            break;
    }

    pipefile.Delete();
    

    return 0;
    
}
cpp 复制代码
//pipe.hpp
#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <cstring>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

const std::string gcommfile = "./fifo";
#define ForRead 1
#define ForWrite 2
class Fifo
{
public:
    Fifo(const std::string &commfile = gcommfile)
        : _commfile(commfile), _mode(0666), _fd(-1)
    {
    }
    // 1、创建管道
    void Build()

    {
        if (IsExists())
            return;
        umask(0);
        int n = mkfifo(_commfile.c_str(), _mode);
        if (n < 0)
        {
            std::cerr << " mkfifo error:" << strerror(errno) << "errno:" << errno << std::endl;
            exit(1);
        }
        std::cerr << " mkfifo error:" << strerror(errno) << "errno:" << errno << std::endl;
    }
    // 2、打开管道
    void Open(int mode)
    {
        //在通信没有开始之前,如果读端打开,写端没有打开,读端open就会阻塞,直到client(写端)打开
        if (mode == ForRead)

            _fd = open(_commfile.c_str(), O_RDONLY);

        else if(mode == ForWrite)
                _fd = open(_commfile.c_str(), O_WRONLY);
    }


    void Send(const std::string &msgin)
    {
        ssize_t n=write(_fd,msgin.c_str(),msginsize());
        (void)n;

    }
    void Recv(const std::string &msgout)
    {
        char buffer[128];

        ssize_t n=read(_fd,buffer,sizeof(buffer)-1);
        if(n>0)
        {
            buffer[n]=0;
            *msgout=buffer;
            return n;
        }
        else if (n==0)
        {
            return 0;
        }
        else 
        {
            return -1;
        }
    }
    // 3、删除管道
    void Delete()
    {
        if (!IsExists())
            return;
        int n = unlink(_commfile.c_str());
        (void)n;
    }
    ~Fifo()
    {
    }

private:
    bool IsExists()
    {
        struct stat st;
        int n = stat(_commfile.c_str(), &st);
        if (n == 0)
        {
            std::cout << "file exists" << std::cout << endl;
            return true;
        }
        else
        {
            std::cout << "file not exist exists:" << errno << std::endl;
            return false;
        }
    }

private:
    std::string _commfile;
    mode_t _mode;
    int _fd;
};
cpp 复制代码
//Makefile
.PHONY:all
all: Client Server

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

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

.PHONY: clean
clean:
	rm -f Server Client

二、system V共享内存

1、原理是什么?

1、映射到进程的虚拟空间地址的共享区。2、共享内存是一个简化版本的动态库映射。

3、共享内存=共享内存管理结构体+共享内存本身

共享内存需要被操作系统管理起来

4、使用共享内存的步骤:1、创建2、关联链接3、使用()4、去关联5、释放共享内

共享内存是什么?

答:采用多个进程,使用虚拟地址空间映射的方式,让不同的进程看到同一个内存块。

接口:

相关推荐
unDl IONA6 小时前
服务器部署,用 nginx 部署后页面刷新 404 问题,宝塔面板修改(修改 nginx.conf 配置文件)
运维·服务器·nginx
零号全栈寒江独钓6 小时前
基于c/c++实现linux/windows跨平台获取ntp网络时间戳
linux·c语言·c++·windows
Web极客码6 小时前
WordPress管理员角色详解及注意事项
运维·服务器·wordpress
左手厨刀右手茼蒿7 小时前
Linux 内核中的进程管理:从创建到终止
linux·嵌入式·系统内核
geinvse_seg7 小时前
中小团队如何低成本搭建项目管理系统?基于 Ubuntu 的 Dootask 私有化部署实战
linux·运维·ubuntu
星辰徐哥7 小时前
鸿蒙金融理财全栈项目——上线与运维、用户反馈、持续迭代优化
运维·金融·harmonyos
CSCN新手听安7 小时前
【linux】高级IO,以ET模式运行的epoll版本的TCP服务器实现reactor反应堆
linux·运维·服务器·c++·高级io·epoll·reactor反应堆
丶伯爵式7 小时前
Ubuntu 24.04 更换国内软件源指南 | 2026年3月26日
linux·运维·ubuntu·国内源·升级
左手厨刀右手茼蒿7 小时前
Linux 内核中的 DMA 管理:从缓冲区到传输
linux·嵌入式·系统内核
xingyuzhisuan7 小时前
租用GPU服务器进行深度学习课程教学的实验环境搭建
运维·人工智能·深度学习·gpu算力