当前位置: 首页 > news >正文

深入解析:【Linux】零基础学习命名管道-共享内存

深入解析:【Linux】零基础学习命名管道-共享内存

文章目录

  • 背景
    • 存储
  • 建立命名管道
    • 命令行创建
    • mkfifo函数实现通信
  • 共享内存
    • 原理
      • shmget
      • shmat
      • shmdt
      • shmctl
  • 实现共享内存

背景

匿名管道有一个缺点,就是只能血缘间通信,而我们想要让两个毫不相干的进程进行通信,就要用到命名管道

存储

要两个毫不相干的进程通信,首先要看到同一个管道文件命名管道如何做到的呢同一路径下的同一文件名文件路径具有唯一性
所以,命名管道存储在文件系统中,有自己的文件路径和inode但是不会向磁盘中刷数据数据传输发生在内存级缓冲区中

所以,纯内存级缓冲区的通信方法有:
匿名管道,共享内存,消息队列

建立命名管道

命令行创建

1,命名管道可以直接在命令行创建

mkfifo “管道名”

在这里插入图片描述

可以看到我创建了一个管道,向里面写入!

在这里插入图片描述

可以看到卡住了,那是因为卡在文件缓冲区了,我没有读取

在这里插入图片描述
并且我们查看文件大小,发现还是0,说明没刷盘,读取之后结束

删除管道用unlink, 比如这里

unlink myfile

mkfifo函数实现通信

函数:

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

用函数实现两个进程通信

头文件:封装类,完成命名管道初始化和清理

#include<iostream>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <string.h>#include <stdio.h>#define FIFO_FILE "./myfile"#define MODE 0664enum{FIFO_CREAT_FILE=1,FIFO_DELETE_FILE,FIFO_OPEN_FILE};class Init{public:Init(){int n=mkfifo(FIFO_FILE,MODE);if(n==-1){perror("mkfifo");exit(FIFO_CREAT_FILE);}}~Init(){int m=unlink(FIFO_FILE);if(m==-1){perror("unlink");exit(FIFO_DELETE_FILE);}}};

==读端:打开文件即可,要是写端没准备好,我们还需要等写端打开,==不断写入,如果x=0,说明写端关闭了,那我也关闭

#include "commen.h"
using namespace std;
int main()
{
Init it;
int fd=open(FIFO_FILE,O_RDONLY); //读端得等写端打开文件
cout<<"server ready done"<<endl;
if(fd==-1)
{
perror("open");
exit(FIFO_OPEN_FILE);
}
while(true)
{
char buffer[1024]={0};
int x=read(fd,buffer,sizeof(buffer));
if(x>0)
{
buffer[x]=0;
cout<<"client say:"<<buffer<<endl;
}
else if(x==0)
{
printf("client quit! me too! string errno %s,errno %d",strerror(errno),errno);
break;
}
else{
break;
}
}
return 0;
}

写端:打开文件,从键盘上获取字符串,写入文件

#include "commen.h"
using namespace std;
int main()
{
int fd=open(FIFO_FILE,O_WRONLY);
if(fd<0)
{
perror("open");
exit(FIFO_CREAT_FILE);
}
cout<<"client ready done"<<endl;
string line;
while(true)
{
cout<<"please enter:"<<endl;
getline(cin,line);
write(fd,line.c_str(),line.size());
}
close(fd);
return 0;
}

在这里插入图片描述

共享内存

原理


操作系统在物理内存中开辟一块物理内存,供两个进程交流,

操作系统中肯定有很多共享内存,操作系统肯定要管理先描述再组织

释放一个共享内存,先去关联再释放

注意:
1,共享内存没有同步机制
2,共享内存通信速度最快(因为他拷贝最少)
3,共享内存数据都由用户自己控制

上代码:

shmget

int shmget(key_y key , size_t size , int shmflg);

int 返回共享内存标识符
key:具有唯一性,保证进程能找到
size:共享内存大小
shmflg:如何设置共享内存O_CREAT没有就创建,有就打开
O_CREAT | O_EXIT,没有就创建,有返回错误
O_EXIT 不单独使用

key 和 shmid(shmget返回值)区别
key操作系统内标定唯一性
shmid只在你的进程用来表示资源唯一性

学习key
1,key 在内核中要具有唯一性,方便进程找到
2,第一个进程设置key,第二个进程拿着相同的key就能找到相同位置
3,key存在哪里?共享内存结构体中
4,key其实类似路径 它怎么来的 ?函数

key_t ftok(const char* pathname, int proj_id id);
pathname是用户自己定义的路径/home/jib,id也是用户自己指定的

共享内存生命周期是随内核的,也就是用户不关闭,共享内存会一直存在,除非内核重启
共享内存查看: ipcs -m
共享内存删除:ipcrm -m shmid
在这里插入图片描述
nattch表示哪个进程关联到此共享内存

shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);

功能:将共享内存关联到进程中,

shmid:共享内存的标识符
shmaddr:一般设置nullptr,核心自动选择地址
shmflg: 设置0 读写权限

shmdt

int shmdt(const void *shmaddr);

功能:将进程去关联
shmaddr 共享内存起始地址

注意去关联,不代表释放共享内存

shmctl

功能:控制共享内存

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

cmd有3个动作
在这里插入图片描述

实现共享内存

共享内存没有同步机制,也就是我们写入时,不会自动清理缓存区,就会一直打印重复数据

所以我们加了管道,通知读端
commen.hpp

#include <iostream>#include <string.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <unistd.h>#include <sys/shm.h>using namespace std;//共享内存给的是4096整数倍字节大小,//就算定义 4097,给你的其实是4096*2,但是你访问4098又会报错const int size=4096;const string pathname="/home/jib";const int proj_id = 0x6666;key_t GetKey(){int k=ftok(pathname.c_str(),proj_id);if(k<0){perror("ftok");exit(1);}printf("ftok success! key is 0x%x\n", k);return k;}int GetShareMemHelper(int flag){key_t k=GetKey();int shmid=shmget(k,size,flag);if(shmid<0){perror("shmget");exit(2);}printf("shmget success : %d",k);return shmid;}int Createshm(){return GetShareMemHelper(IPC_CREAT| 0666);}int Getshm(){return GetShareMemHelper(IPC_CREAT|0666);}#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#define FIFO_FILE "./myfile"#define MODE 0664enum{FIFO_CREAT_FILE=1,FIFO_DELETE_FILE,FIFO_OPEN_FILE};class Init{public:Init(){int n=mkfifo(FIFO_FILE,MODE);if(n==-1){perror("mkfifo");exit(FIFO_CREAT_FILE);}}~Init(){int m=unlink(FIFO_FILE);if(m==-1){perror("unlink");exit(FIFO_DELETE_FILE);}}};

server.cc

#include "commen.hpp"
#include "log.hpp"
using namespace std;
int main()
{
Log log;
Init init;
int shmid=Createshm();
char* shmaddr=(char*)shmat(shmid,nullptr,0);
int fd=open(FIFO_FILE,O_CREAT|O_RDONLY);
log(Info,"server open success");
if(fd<0)
{
log(Fetal,"error string : %s,error :%d",strerror(errno),errno);
exit(FIFO_CREAT_FILE);
}
struct shmid_ds shmds;
while(true)
{
char c;
size_t s=read(fd,&c,1);
if(s<0)
break;
else if(s==0)
break;
cout<<"Client Say:"<<shmaddr<<endl;
//sleep(1);
shmctl(shmid, IPC_STAT, &shmds);
cout << "shm size: " << shmds.shm_segsz << endl;
cout << "shm nattch: " << shmds.shm_nattch << endl;
printf("shm key: 0x%x\n",  shmds.shm_perm.__key);
cout << "shm mode: " << shmds.shm_perm.mode << endl;
}
shmdt(shmaddr);
shmctl(shmid,IPC_RMID,nullptr);
close(fd);
return 0;
}

client.cc

#include "commen.hpp"
#include "log.hpp"
using namespace std;
int main()
{
Log log;
int shmid=Getshm();
char* shmaddr=(char*)shmat(shmid,nullptr,0);
int fd=open(FIFO_FILE,O_CREAT| O_WRONLY,MODE);
if(fd<0)
{
log(Fetal,"error string :%s,errno :%d",strerror(errno),errno);
exit(FIFO_OPEN_FILE);
}
while(true)
{
cout<<"please enter :";
fgets(shmaddr,4096,stdin);
write(fd,"c",1);
}
shmdt(shmaddr);
return 0;
}

实现两个进程通信

http://www.jsqmd.com/news/387704/

相关文章:

  • 华黎卡的排列构造
  • 2026年海外GEO系统优化推广服务商Top 5揭晓:谁在真正驱动中国品牌出海? - 深圳昊客网络
  • AI元人文:界面东西——在诗性与逻各斯间
  • 我的算法修炼之路--8——预处理、滑窗优化、前缀和哈希同余,线性dp,图+并查集与逆向图 - 指南
  • JVM学习笔记:第三章——运行时数据区(部分)
  • 自助建站系统哪个好?自助建站软件选哪个好 - 码云数智
  • vue3微信小程序Nodejs无人机监控管理平台设计与实现
  • 小程序快速开发平台有哪些?小程序第三方开发平台推荐 - 码云数智
  • 基于SpringBoot和Vue的校园在线拍卖高效的系统设计与搭建
  • nodejs+Vue3+AI算力资源网上商城系统的设计与实现
  • 从Cyberhub到Aram Nagar:一个理性与创意兼具之人的内心漫游
  • 如何创建自己的微信小程序呢? - 码云数智
  • 零基础如何快速制作自己的公司网站呢? - 码云数智
  • 会员卡充值消费系统怎么做 - 码云数智
  • 小程序开发需要多少钱?小程序开发方式及费用 - 码云数智
  • 如何开发在线培训课程平台,知识付费小程序怎么做 - 码云数智
  • 会员管理系统软件哪个好?主流软件核心优势与适用场景 - 码云数智
  • 微信小程序会员管理系统怎么做 - 码云数智
  • USB TYPC-C做USB2.0使用
  • 实用指南:window雷池WAF安装运行文档
  • 企业网站怎么建立,如何给自己的公司建网站 - 码云数智
  • 小程序商城哪个平台好?小程序商城制作平台对比 - 码云数智
  • 微信商城小程序怎么弄,电商小程序搭建流程 - 码云数智
  • 题解:CF2195E
  • 2026SaaS小程序制作平台及其核心特点、价格与适用场景 - 码云数智
  • 微信小程序怎么制作自己的小程序 - 码云数智
  • C++初学的常见问题 之二
  • 普通人如何杀入AI赛道?(附岗位薪资与避坑指南)收藏这份AI转行指南,轻松入局高薪赛道!
  • DeepSeek V4“泄露”性能惊艳:编码数学双封神,程序员必看收藏!
  • 制造企业研发管理体系化升级与数字化转型落地建议书 - 指南