热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Linux进程间通信共享内存

共享内存IPC原理共享内存进程间通信机制主要用于实现进程间大量的数据传输,下图所示为进程间使用共享内存实现大量数据传输的示意图:共享内存是在内存中单独开辟的一段内存空间,这段内存空
共享内存 IPC 原理

共享内存进程间通信机制主要用于实现进程间大量的数据传输,下图所示为进程间使用共享内存实现大量数据传输的示意图:

技术分享图片

共享内存是在内存中单独开辟的一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问的时间等。该数据结构定义如下:

from /usr/include/linux/shm.h

struct shmid_ds {
    struct ipc_perm     shm_perm;   /* operation perms 操作权限 */
    int         shm_segsz;  /* size of segment (bytes) 段长度大小 */
    __kernel_time_t     shm_atime;  /* last attach time 最近attach时间 */
    __kernel_time_t     shm_dtime;  /* last detach time 最近detach时间 */
    __kernel_time_t     shm_ctime;  /* last change time 最近change时间 */
    __kernel_ipc_pid_t  shm_cpid;   /* pid of creator 创建者pid */
    __kernel_ipc_pid_t  shm_lpid;   /* pid of last operator 最近操作pid */
    unsigned short      shm_nattch; /* no. of current attaches */
    unsigned short      shm_unused; /* compatibility */
    void            *shm_unused2;   /* ditto - used by DIPC */
    void            *shm_unused3;   /* unused */
};

两个进程在使用此共享内存空间之前,需要在进程地址空间与共享内存空间之间建立联系,即将共享内存空间挂载到进程中。

系统对共享内存做了以下限制:

#define SHMMAX 0x2000000         /* max shared seg size (bytes) 最大共享段大小 */
#define SHMMIN 1             /* min shared seg size (bytes) 最小共享段大小 */
#define SHMMNI 4096          /* max num of segs system wide */
#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))
#define SHMSEG SHMMNI            /* max shared segs per process */
Linux 共享内存管理

1.创建共享内存

#include 
#include 

/*
 * 第一个参数为 key 值,一般由 ftok() 函数产生
 * 第二个参数为欲创建的共享内存段大小(单位为字节)
 * 第三个参数用来标识共享内存段的创建标识
 */
int shmget(key_t key, size_t size, int shmflg);

2.共享内存控制

#include 
#include 

/*
 * 第一个参数为要操作的共享内存标识符
 * 第二个参数为要执行的操作
 * 第三个参数为 shmid_ds 结构的临时共享内存变量信息
 */
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

3.映射共享内存对象

系统调用 shmat() 函数实现将一个共享内存段映射到调用进程的数据段中,并返回内存空间首地址,其函数声明如下:

#include 
#include 

/*
 * 第一个参数为要操作的共享内存标识符
 * 第二个参数用来指定共享内存的映射地址,非0则为此参数,为0的话由系统分配
 * 第三个参数用来指定共享内存段的访问权限和映射条件
 */
void *shmat(int shmid, const void *shmaddr, int shmflg);

4.分离共享内存对象

在使用完毕共享内存空间后,需要使用 shmdt() 函数调用将其与当前进程分离。函数声明如下:

#include 
#include 

/*
 * 参数为分配的共享内存首地址
 */
int shmdt(const void *shmaddr);
共享内存在父子进程间遵循的约定
1.使用 fork() 函数创建一个子进程后,该进程继承父亲进程挂载的共享内存。
2.如果调用 exec() 执行一个新的程序,则所有挂载的共享内存将被自动卸载。
3.如果在某个进程中调用了 exit() 函数,所有挂载的共享内存将与当前进程脱离关系。
程序实例

申请一段共享内存,父进程在首地址处存入一整数,子进程读出。

#include 
#include 
#include 
#include 
#include 
#include 

#define SHM_SIZE 1024

int main()
{
    int shm_id, pid;
    int *ptr = NULL;

    /* 申请共享内存 */
    shm_id = shmget((key_t)1004, SHM_SIZE, IPC_CREAT | 0600);

    /* 映射共享内存到进程地址空间 */
    ptr = (int*)shmat(shm_id, 0, 0);

    printf("Attach addr is %p \n", ptr);

    *ptr = 1004;

    printf("The Value of Parent is : %d \n", *ptr);

    if((pid=fork()) == -1){
        perror("fork Err");
        exit(0);
    }
    else if(!pid){
        printf("The Value of Child is : %d \n", *ptr);
        exit(0);
    }else{
        sleep(1);

        /* 解除映射 */
        shmdt(ptr);
        
        /* 删除共享内存 */
        shmctl(shm_id, IPC_RMID, 0);
    }

    return 0;
}

输出结果:

技术分享图片

Linux进程间通信 --- 共享内存


推荐阅读
  • 深入解析Android Activity生命周期
    本文详细探讨了Android中Activity的生命周期,通过实例代码和详细的步骤说明,帮助开发者更好地理解和掌握Activity各个阶段的行为。 ... [详细]
  • 本文探讨了 Boost 库中的 Program Options 组件,这是一个强大的工具,用于解析命令行参数和配置文件。文章介绍了如何正确设置和使用该组件,包括处理复杂选项和负数值的方法。 ... [详细]
  • 解决 Pytest 运行时出现 FileNotFoundError 的方法
    在使用 Pytest 进行测试时,可能会遇到 FileNotFoundError 错误,提示无法找到指定的文件或目录。本文将探讨该错误的原因及解决方案。 ... [详细]
  • HDU1085 捕获本·拉登!
    问题描述众所周知,本·拉登是一位臭名昭著的恐怖分子,他已失踪多年。但最近有报道称,他藏匿在中国杭州!虽然他躲在杭州的一个洞穴中不敢外出,但近年来他因无聊而沉迷于数学问题,并声称如果有人能解出他的题目,他就自首。 ... [详细]
  • BL550721、特点液晶驱动输出:Common输出4线,Segment输出36线内置显示寄存器364144bit2线串行接口(SCL,SDA)内置震荡电路内置液晶驱动电源电路13 ... [详细]
  • 本文详细介绍了一种实现PopupWindow全屏显示且能有效隐藏虚拟按键的技术方案,适用于Android开发。此方法经过实际测试,表现良好,兼容性优秀。 ... [详细]
  • BeautifulSoup4 是一个功能强大的HTML和XML解析库,它能够帮助开发者轻松地从网页中提取信息。本文将介绍BeautifulSoup4的基本功能、安装方法、与其他解析工具的对比以及简单的使用示例。 ... [详细]
  • SpringBoot新手入门指南
    本文旨在为初次接触SpringBoot的开发者提供一份详细的入门指导,包括如何快速搭建并运行一个简单的SpringBoot应用。通过本文,读者将了解Maven项目的构建、必要的配置文件设置以及基本的应用开发流程。 ... [详细]
  • IEC60825激光产品安全标准详解
    随着激光技术在全球范围内的广泛应用,尤其是激光投影显示技术的兴起,了解和遵守相关的安全标准变得尤为重要。本文将详细介绍IEC60825激光产品安全标准及其重要性。 ... [详细]
  • Mysqlcheck作为MySQL提供的一个实用工具,主要用于数据库表的维护工作,包括检查、分析、修复及优化等操作。本文将详细介绍如何使用Mysqlcheck工具,并提供一些实践建议。 ... [详细]
  • 本文介绍了Linux内核中TCP的三种接收队列:Prequeue、sk_receive_queue和Backlog。这些队列在数据包处理过程中扮演着重要角色,帮助提高系统性能和效率。 ... [详细]
  • 探讨并提供解决方案以应对 'view is not in the window hierarchy' 的错误提示。 ... [详细]
  • 本文介绍了如何处理MySQL数据库中表 'xdb.auditlog' 被标记为已损坏的问题,并提供了解决方案。 ... [详细]
  • 本文介绍了多种Eclipse插件,包括XML Schema Infoset Model (XSD)、Graphical Editing Framework (GEF)、Eclipse Modeling Framework (EMF)等,涵盖了从Web开发到图形界面编辑的多个方面。 ... [详细]
  • 本文介绍了如何使用Maven命令对Spring Boot项目中的子模块进行独立打包,包括依赖树的查看、项目的运行和打包等基本操作。 ... [详细]
author-avatar
手机用户2502908237
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有