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、释放共享内

共享内存是什么?

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

接口:

相关推荐
Lonely 净土3 小时前
Linux 运维文件写入操作
linux·运维·服务器·文件管理
城管不管3 小时前
重生——第十一次面试之挖财一面2026.8.19已OC
java·服务器·jvm·数据库·spring·面试·职场和发展
飞英思特无线充电3 小时前
严苛场景巡检机器人的无线补能设计:点位、BMS、认证与运维边界
运维·机器人
Jimmy_jimi4 小时前
利用nginx代理完成url重定位
运维·nginx
liuyicenysabel4 小时前
多服务上线日记三:
运维·服务器·笔记·学习
吠品6 小时前
Wine 在 Linux 上运行 Windows 软件完整指南
java·linux·服务器
一只鹿鹿鹿6 小时前
大数据中心安全系统解决方案(Word文件)
大数据·运维·物联网·安全·政务
深念Y8 小时前
从 Windows 迁移到 Linux 开发环境的记录
linux·windows·链接·bun·ram·imdisk
AuTumn-L8 小时前
使用 SSH 密钥认证实现安全免密登录
服务器·安全·ssh
领创工作室8 小时前
GitHub Workflows 全面解析:从核心概念到开源实现
运维·github