C++ 共享内存相关的API

news/2024/11/29 6:30:33/

C++ 共享内存相关的API

    • 1.什么是共享内存
        • 1.共享内存的概念
        • 2.共享内存的原理
        • 3.共享内存使用注意点
    • 2.共享内存有关API的操作函数及示例
        • 1.新建共享内存-shmget
        • 2.连接共享内存到当前的地址空间-shnat
        • 3.当前进程分离共享内存shmdt
        • 4.控制共享内存-shmctl
        • 5.共享内存操作示例
    • 3.共享内存的使用场景有哪些

1.什么是共享内存

1.共享内存的概念

共享内存是一种操作系统提供的机制,用于实现多个进程之间共享数据的方式。在共享内存中,多个进程可以访问同一块物理内存区域,从而实现数据的共享和通信,而不需要进行显式的数据拷贝或进程间的消息传递。

2.共享内存的原理

共享内存的基本原理是将一块内存区域映射到多个进程的地址空间中,使得这些进程可以直接访问该内存区域。这种共享的内存区域被称为共享内存段。多个进程可以通过读写共享内存段来实现数据的共享和交互。

3.共享内存使用注意点

使用共享内存可以提高数据访问和传输的效率,因为数据直接存储在物理内存中,进程可以直接读写内存,而不需要进行数据的拷贝或消息的传递。然而,由于多个进程可以同时访问共享内存,因此需要采取适当的同步机制,如锁或信号量,来保证数据的一致性和避免竞态条件。

2.共享内存有关API的操作函数及示例

1.新建共享内存-shmget
int shmget (key_t __key, size_t __size, int __shmflg)

key:共享内存的键值,可以理解为共享内存的唯一性标记
size:共享内存的大小
shmflag:创建进程和其他进程的读写权限标识
返回值:响应的共享内存的标识符,失败返回-1

2.连接共享内存到当前的地址空间-shnat
void *shmat (int __shmid, const void *__shmaddr, int __shmflg)

shm_id:共享内存标识符
shm_addr:指定共享内存连接到当前进程的地址;通常为0,表示由系统来选择
shmflag:标志位
返回值:指向共享内存第一个字节的指针,失败返回-1

3.当前进程分离共享内存shmdt
 int shmdt (const void *__shmaddr)
4.控制共享内存-shmctl
int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) 

和信号量的semctl函数类似,控制共享内存
shm_id:共享内存标识符
command:有三个值:

IPC_STAT:获取共享内存的状态信息,包括共享内存的大小、创建时间、最后访问时间、进程ID等。IPC_SET:设置共享内存的状态信息,例如修改共享内存的权限、最后访问时间等。IPC_RMID:删除共享内存段,释放分配的内存资源。

需要注意的是,shmctl函数的第三个参数__buf是一个指向shmid_ds结构体的指针,用于传递共享内存的状态信息。在使用IPC_STAT命令时,__buf指向的结构体将被填充共享内存的状态信息。在使用IPC_SET命令时,__buf指向的结构体应该包含要设置的共享内存状态信息。在使用IPC_RMID命令时,__buf可以为NULL。

除了上述常用的命令,还有其他一些命令可供使用,例如:

IPC_INFO:获取系统中共享内存的状态信息,包括共享内存的总数、使用的共享内存段数量、共享内存的最大大小等。SHM_LOCK:锁定共享内存,阻止其被交换到磁盘上。SHM_UNLOCK:解锁共享内存,允许其被交换到磁盘上
5.共享内存操作示例
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>using namespace std;int main() {int shmId; // 共享内存ID号char *shmPtr; // 指向共享内存的指针key_t shmKey; // 创建共享内存的键值size_t shmSize; // 共享内存的大小shmKey = ftok(".", 'a'); // 获取用于创建共享内存的键值shmSize = getpagesize(); // 获取系统内存页的大小// 创建共享内存shmId = shmget(shmKey, shmSize, IPC_CREAT | 0666);if (shmId < 0) {cerr << "Error: shmget() failed" << endl;exit(1);}// 映射共享内存到进程的地址空间shmPtr = (char *) shmat(shmId, NULL, 0);if (shmPtr == (char *) -1) {cerr << "Error: shmat() failed" << endl;exit(1);}// 数据写入共享内存strcpy(shmPtr, "Hello, shared memory,this is first write data!");// 读取共享内存中的数据cout << "Shared memory content first read:\n " << shmPtr << endl;//重新写入共享内存strcpy(shmPtr, "Hello, shared memory,this is second write data!");// 读取共享内存中的数据cout << "Shared memory content again:\n\n" << shmPtr << endl;//获取系统中共享内存的状态信息struct shminfo  shm_info;shmctl(shmId, IPC_INFO, (struct shmid_ds*)&shm_info);cout << "共享内存总数: " << shm_info.shmmni << endl;cout << "已使用的共享内存段数量: " << shm_info.shmseg << endl;cout << "共享内存的最大大小: " << shm_info.shmmax << endl;// 分离共享内存if (shmdt(shmPtr) < 0) {cerr << "Error: shmdt() failed" << endl;exit(1);}// 删除共享内存if (shmctl(shmId, IPC_RMID, NULL) < 0) {cerr << "Error: shmctl() failed" << endl;exit(1);}return 0;
}

在这里插入图片描述

3.共享内存的使用场景有哪些

共享内存是多个进程之间共享数据的一种方式,主要有以下场景:

进程间通信:多个进程之间需要共享一些数据或对象,例如操作系统为进程间的通信提供的缓冲区就是使用共享内存实现的。

高性能计算:在高性能计算中,多个进程需要访问共享的数据结构,例如矩阵运算等,使用共享内存可以避免数据拷贝和通信的开销,提高程序性能。

大型数据库:大型数据库需要频繁地进行数据访问和更新,使用共享内存可以提高数据访问效率,缩短数据读写时间。

多进程服务器:多进程服务器需要共享一些全局数据,例如监听端口号、连接池、缓冲区等。

总之,共享内存是在多个进程之间共享数据的重要方式之一。在需要大量数据传输和频繁访问数据的场景中,使用共享内存可以提高程序效率和性能。但是,需要注意使用锁或者其他同步机制来保证数据的一致性和可靠性。


http://www.ppmy.cn/news/1121336.html

相关文章

【Python基础】各种情况的报错汇总

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

中兴R5300 G4服务器iSAC管理员zteroot密码遗失的重置方法及IPV6地址启用设置

本文讲解中兴R5300 G4服务器BMC带外iSAC管理员zteroot密码遗失&#xff0c;无法登录时如何对其进行密码重置&#xff0c;以及iSAC启用IPV6地址的方法。 一、重置中兴R5300 G4服务器iSAC管理员zteroot密码 1、通过SSH登录到iSAC&#xff0c;默认用户名&#xff1a;sysadmin&am…

MySQL与PostgreSQL对比

MySQLPostgreSQL数据类型支持支持JSON&#xff0c;但不如PostgreSQL支持更多的数据类型&#xff0c;如数组、hstore、JSON、JSONB、范围类型等扩展性有一些扩展性&#xff0c;但不如PostgreSQL支持自定义数据类型、函数、操作符&#xff0c;具有强大的扩展性SQL兼容性遵循SQL标…

基于Vue+ELement搭建登陆注册页面实现后端交互

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《ELement》。&#x1f3af;&#x1f3af; &#x1…

若依注解学习(一)@Log

Log 涉及到&#xff1a; Log&#xff0c;LogAspect&#xff0c;SecurityUtils&#xff0c;SysUser&#xff0c;SysOperLog&#xff0c;BusinessStatus&#xff0c;StringUtils&#xff0c;ServletUtils AsyncManager&#xff0c;AsyncFactory&#xff…

时间轮算法

思考 假如现在有个任务需要3s后执行&#xff0c;你会如何实现&#xff1f; 线程实现&#xff1a;让线程休眠3s 如果存在大量任务时&#xff0c;每个任务都需要一个单独的线程&#xff0c;那这个方案的消耗是极其巨大的&#xff0c;那么如何实现高效的调度呢&#xff1f; 时…

多线程-定时器、线程池

阻塞队列介绍标准库阻塞队列使用基于阻塞队列的简单生产者消费者模型。实现一个简单型阻塞队列 &#xff08;基于数组实现&#xff09; 定时器标准库的使用 线程池使用线程数目确定 阻塞队列介绍 不要和之前学多线程的就绪队列搞混&#xff1b; 阻塞队列&#xff1a;也是一个…

springcloud3 分布式事务解决方案seata之AT模式5

一 seata的AT模式 1.1 AT模式与XA模式 XA模式一阶段不提交事务&#xff0c;锁定资源&#xff1b;AT模式一阶段直接提交&#xff0c;不锁定资源。 XA模式依赖数据库机制实现回滚&#xff1b;AT模式利用数据快照实现数据回滚。 XA模式强一致&#xff1b;AT模式最终一致 1.2 …