IPC----共享内存

本文详细介绍了共享内存的概念及其在进程间通信中的应用。包括共享内存的建立过程、关键函数的使用方法,以及通过示例代码展示了如何创建、映射和删除共享内存。此外,还讨论了共享内存的特点和System V IPC通信的优点与局限。

1.什么是共享内存:共享内存允许两个或多个进程访问给定的同一块存储区域。已知当一个进程被启动时,系统会为其创建一个 0~4G 的虚拟内存空间, 根据虚拟地址与物理地址之间的映射关系,进程可以通过操作虚拟地址,实现对物理页面的操作。
一般情况下,每个进程的虚拟地址空间会与不同的物理地址进行映射,但是当使用共享内存进行通信时,系统会将同一段物理内存映射给不同的进程。
两个进程的虚拟地址空间与共享内存之间的映射关系如下图
这里写图片描述
系统中的物理内存和虚拟内存都通过页面来管理,为多个进程分配共享内存,实际是为进程分配一个或多个物理页面,因此,共享内存的大小必须是系统中页面大小的整数倍
2.共享内存建立的过程
<1>首先将虚拟内存空间与共享
内存进行映射,
<2>映射完成后,进程对虚拟地址的读写,就相当于直接对物理内存
的读写。
<3>另外,与申请堆空间类似,当通信完成之后,也应释放物理内存,解除进程与共享内存的映射关系。
3.共享内存有关的函数

1.int shmget(key_t key, size_t size, int shmflg);
//功能是创建一块新的共享内存,或打开一块已经存在的共享内存
//第一个参数key,代表共享内存的键值
//第二个参数size用于设置共享内存的大小
//第三个参数 shmflg 用于设置 shmget()函数的创建条件(一般设置为 IPC_CREAT 或 IPC_EXCL)及进程对共享内存的读写权限。
2.void *shmat(int shmid, const void *shmaddr, int shmflg);
//功能是进行地址映射,将共享内存映射到进程虚拟地址空间中
//第一个参数 shmid 为共享内存标识符,该标识符一般由shmget()函数返回;
//参数 shmaddr 为一个指针类型的传入参数,用于指定共享内存映射到虚拟内存时的虚拟地址,当设置为 NULL 时,映射地址由系统决定;
//参数 shmflg 用于设置共享内存的使用方式,若 shmflg 设置为 SHM_RDONLY,则共享内存将以只读的方式进行映射,当前进程只能从共享内存中读取数据。
3.int shmdt(const void *shmaddr);
//功能是解除物理内存与进程虚拟地址空间的映射关系
4.int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//功能是对已存在的共享内存进行操作,具体的操作由参数决定
//参数 shmid 表示共享内存标识符;
//参数 cmd 表示要执行的操作,常用的设置为IPC_RMID,功能为删除共享内存;
//参数 buf 用于对共享内存的管理信息进行设置,该参数是一个结构体指针,
5.struct shmid_ds *buf结构体如下
struct shmid_ds {
struct ipc_perm shm_perm; //所有者和权限标识
size_t shm_segsz; //共享内存大小
time_t shm_atime; //最后映射时间
time_t shm_dtime; //最后解除映射时间
time_t shm_ctime; //最后修改时间
pid_t shm_cpid; //创建共享内存进程的 id
pid_t shm_lpid; //最近操作共享内存进程的 id
shmatt_t shm_nattch; //与共享内存发生映射的进程数量
...
};

共享内存代码

//com.h
#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/wait.h>
#include<unistd.h>

#define PATH "."
#define SIZE 256
int GetShm();
char* At_Shm(int shm_id);
int Delete_Shm(char* addr);
int Rm_Shm(int shm_id);

int GetShm(){
    key_t key=ftok(PATH,0);
    if(key==-1){
        perror("ftok");
        exit(1);
    }
    int flag=IPC_CREAT|0666;
    int shm_id=shmget(key,SIZE,flag);
    if(shm_id==-1){
        perror("shmget");
        exit(1);
    }
    return shm_id;
}
char* At_Shm(int shm_id){
    return (char*)shmat(shm_id,NULL,0);
}
int Delete_Shm(char* addr){
    return shmdt(addr);
}
int Rm_Shm(int shm_id){
    return shmctl(shm_id,IPC_RMID,NULL);
}
//myshm.c
#include<stdio.h>
#include<string.h>
#include"com.h"
int main()
{
    int shm_id=GetShm();
    pid_t pid=fork();
    if(pid<0){
        perror("fork");
        exit(1);
    }
    else if(pid==0){
        //child
        char* buf=At_Shm(shm_id);
        int i=0;
        while(i<60){
            buf[i]='A'+i;
            i++;
        }
        buf[59]='\0';
        Delete_Shm(buf);     //删除映射
    }
    else{
        //father
        char* buf=At_Shm(shm_id);
        sleep(2);
        printf("%s\n",buf);
        waitpid(pid,NULL,0);
        Rm_Shm(shm_id);
    }

    return 0;
}

运行结果
这里写图片描述
3.共享内存的特点
(1)共享内存是进程间通信最快的方式。
(2)共享内存没有保护机制,需要信号量控制。
(3)共享内存的基本单位是页,即大小最小是4K,且是向上取整数页的。
(4)共享内存的生命周期是随内核的。
4.systemV IPC通信特点
优点
1. 信息共享:Web服务器,通过网页浏览器使用进程间通信来共享web文件(网页等)和多媒体;
2. 加速:维基百科使用通过进程间通信进行交流的多服务器来满足用户的请求;
3. 模块化;
4. 私有权分离;
缺点
1.采用了某种形式的内核开销,降低了性能;
2.几乎大部分IPC都不是程序设计的自然扩展,往往会大大地增加程序的复杂度。

源码来自:https://pan.quark.cn/s/a4b39357ea24 《C++ Primer》作为C++编程领域中的一部权威著作,主要服务于初学者和经验丰富的开发者,致力于帮助他们深入掌握C++的核心知识。 第一章通常会详细讲解C++语言的基础概念和语法结构,包括变量的使用、数据类型的分类、常量的定义、运算符的应用以及基础的输入输出操作。 接下来,我们将对这一章中的核心知识点和可能的习题解答进行深入分析。 ### 1. 变量与数据类型在C++编程中,变量被视为存储数据的媒介。 每一个变量都必须预先声明其数据类型,常见的数据类型有整型(int)、浮点型(float)、双精度浮点型(double)以及字符型(char)。 例如:```cppint age = 25; // 声明一个整型变量age并赋予其初始值25float weight = 70.5f; // 声明一个浮点型变量weight并赋予其初始值70.5char grade = A; // 声明一个字符型变量grade并赋予其初始值A```### 2. 常量与字面量常量指的是不可更改的值,可以通过`const`关键字进行声明。 例如:```cppconst int MAX_SIZE = 100; // 声明一个整型常量MAX_SIZE,其值为100```字面量是指程序中直接书写的值,如`42`、`3.14`或`"Hello"`。 ### 3. 运算符C++提供了种运算符,涵盖了算术运算符(+,-,*,/,%)、比较运算符(==,!=,<,>,<=,>=)、逻辑运算符(&&,||,!)以及赋值运算符(=,+=,-=,*=,/=,%=)等。 ### 4. 输入与输出在C++中,使用`std::cin`来实现输...
内容概要:本文详细介绍了一个基于C++的仓库存储管理系统的设计与实现,涵盖了项目背景、目标、挑战及解决方案,并系统阐述了整体架构设计、数据库建模、功能模块划分、权限安全、并发控制、数据一致性保障、异常处理与可扩展性等关键内容。通过面向对象编程思想,采用分层架构与模块化解耦设计,结合STL容器、线程、锁机制等C++核心技术,实现了高效的库存管理功能,包括入库、出库、盘点、调拨、权限控制、日志追踪与智能报表分析。文中还提供了核心类如Inventory(库存)、User(用户权限)、LogEntry(操作日志)及WarehouseManager(主控制器)的代码示例,展示了数据结构设计与关键算法逻辑。; 适合人群:具备C++编程基础,熟悉面向对象设计与基本数据结构的软件开发人员,尤其适合从事企业级管理系统开发或希望深入理解系统架构设计的中级开发者(工作1-3年);也适用于计算机相关专业学生进行课程设计或毕业项目参考; 使用场景及目标:①学习如何使用C++构建复杂业务系统的整体架构与模块划分方法;②掌握高并发、数据一致性、权限控制、异常处理等企业级系统关键技术的实现思路;③理解仓储管理业务流程及其在软件系统中的建模与落地方式;④为开发类似ERP、MES等后台管理系统提供技术原型与设计参考; 阅读建议:此资源不仅提供理论架构与代码片段,更强调系统设计的完整性与工程实践性。建议读者结合代码示例动手实现核心模块,深入理解类之间的关系与交互逻辑,重点关注线程安全、事务管理与权限校验等难点环节,并尝试扩展功能如对接GUI界面或数据库持久化模块,以全面提升系统开发能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值