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

共享内存详解

共享内存

共享内存是一种允许多个进程或线程访问同一块内存区域的机制,它是最快的可用进程间通信(IPC)形式之一。

共享内存的特点

  • 快速性:由于多个进程或线程直接访问同一块内存区域,因此数据交换和通信的速度非常快,远超过其他IPC机制(如命名管道、消息队列等)。
  • 高效性:共享内存减少了数据的冗余拷贝,降低了内存消耗,提高了系统的整体效率。
  • 灵活性:共享内存可以与其他通信机制(如信号量)结合使用,以实现进程间的同步和互斥,从而满足复杂的通信需求。

 


shmget函数 

功能:用于创建贡献内存(如果创建成功,一定是一个新的共享内存)

参数:

  •  key:这个共享内存的名字(共享内存在内核中的唯一性标识)
  • size:这个共享内存大小
  • shmflg:有九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样

IPC_CREAT:如果存在,直接获取它。如果不存在,就创建它

IPC_CREAT | IPC_EXCL 如果不存在创建它。如果存在,出错返回 

返回值: 成功返回一个非负整数,即该共享内存的标识码,失败返回-1。

 ftok函数

功能:ftok函数是一个在Unix和Linux系统中广泛使用的函数,用于生成一个唯一的键(key),这个键通常用于IPC(进程间通信)机制,如消息队列、信号量或共享内存。ftok的名字来源于“file to key”的缩写,意味着它可以根据文件生成一个键。

 参数:

  • pathname:指向文件路径的指针,这个文件通常是项目中的一个已知文件。这个路径不需要指向一个实际存在的文件,但必须是唯一的,以便在不同的项目或实例中生成不同的键。
  • proj_id:一个8位(1字节)的整数,通常用于进一步区分同一路径下的不同键。

 返回值:如果成功,ftok函数返回一个唯一的键(key_t类型)。如果失败,返回-1,并设置errno以指示错误。

 shmat函数

功能:将共享内存连接到进程地址空间中

 参数:

  • shmid:共享内存的标识
  • shamaddr:指定连接的地址
  • shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY

shmaddr为NULL,内核自动选择一个地址

shmaddr不为NULL而且shmflg无SHM_RND标识,则以shmaddr为连接地址

shmaddr不为NULL而且shmflg设置SHM_RND标识,则连接地址会自动向下调整为SHMLBA的整数倍。(shmaddr-(shmaddr%SHMLBA))

shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

 返回值:成功返回一个指针,指向共享内存的第一节,失败返回-1。

shmdt函数

功能:将共享内存和当前线程脱离

参数: 

  •  shmaddr:之前调用shmat返回的指针

返回值:成功返回0,失败返回-1

一个进程打开文件,进程退出时,这个被打开的文件就会被系统自动释放掉(文件的生命周期随进程)

共享内存被创建,如果进程结束,我们没有主动释放,则内存会一直存在,除非重启系统(共享内存生命周期随内核)

shmctl函数 

功能:用于控制共享内存

参数:

  • shmid:由shmget返回的共享内存标识码
  • cmd:将要采取的动作(有三个取值)
  • buf:指向一个保存着共享内存的模式状态和访问权限的数据结构

返回值:成功返回0,失败返回-1


 代码实操

comm.cc#pragma once#include <stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include <unistd.h>#define PATHNAME "."
#define PROJ_ID 0x6666
client.cc
#include"comm.h"int main()
{key_t key = ftok(PATHNAME,PROJ_ID);if(key<0){perror("ftok error");return(-1);}int shmid = shmget(key,4096,IPC_CREAT|IPC_EXCL|0666);if(shmid<0){perror("shmget error");return(-2);}char* addr = (char*)shmat(shmid,nullptr,0);sleep(1);for(int i=0;i<26;i++){addr[i] = 'A' + i;addr[i+1] = '\0';sleep(1);}shmdt(addr);int n = shmctl(shmid,IPC_RMID,NULL);if(n<0){perror("shmctl error");return(-3);}return 0;
}
server.cc
#include"comm.h"int main()
{key_t key = ftok(PATHNAME,PROJ_ID);if(key<0){perror("ftok error");return(-1);}int shmid = shmget(key,4096,IPC_CREAT);if(shmid<0){perror("shmget error");return(-2);}char* addr = (char*)shmat(shmid,nullptr,0);sleep(1);for(int i=0;i<26;i++){printf("read#: %s\n",addr);sleep(1);}shmdt(addr);int n = shmctl(shmid,IPC_RMID,NULL);if(n<0){perror("shmctl error");return(-3);}return 0;
}

 

 


http://www.mrgr.cn/news/34232.html

相关文章:

  • 51WORLD打造土耳其奥斯曼尼耶城市大脑,助力中东城市智慧化转型
  • 深入解析:从URL到页面渲染的完整过程与性能优化【页面渲染、重排、重汇】
  • 仓颉编程语言4,遇到BUG求助
  • 浅谈人工智能技术,对社会经济变革的思考
  • Linux(麒麟系统)多显示器屏幕录制
  • 软件测试实验室如何利用GB/T25000标准建立测试技术体系
  • 828华为云征文 | 云服务器Flexus X实例,Docker集成搭建NGINX
  • 超详细超实用!!!AI编程之cursor编写官网新增轮播效果(三)
  • 【二分算法】模板总结
  • 系统分析师12:系统规划
  • 沁恒CH32V307读写flash出错
  • 远程升级频频失败?你可能忽略了模组差分包…
  • 学生宿舍管理:Spring Boot框架的高效策略
  • Apache Iceberg 概述
  • HOJ网站开启https访问 申请免费SSL证书 部署证书详细操作指南
  • 现代前端框架实战指南:React、Vue.js、Angular核心概念与应用
  • 【数列求值 / B】
  • 手把手教您轻松实现微信/QQ/TIM多开,消息防撤回!
  • 机械手末端快换技术:工业自动化的强大新动力
  • python:django项目知识点02——搭建简易授权码核销系统