0
点赞
收藏
分享

微信扫一扫

linux进程间通信 - 共享内存(shm)

Android开发指南 2022-04-17 阅读 122
linux

共享内存

共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区。在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一个共享内存区的最大字节数shmmax,系统范围内最大共享内存区标识符数shmmni等,可以手工对其调整,但不推荐这样做。请添加图片描述

  • 共享内存是进程间共享数据的一种最快的方法。一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
  • 使用共享内存要注意的是多个进程之间对一个给定存储区访问的互斥。若一个进程正在向共享内存区写数据,则在它做完这一步操作前,别的进程不应当去读、写这些数据。

共享内存有两种方式,即 shm 和 mmap 方式。前者直接共享物理内存,后者通过一个中间文件间接共享内存

共享内存打开创建

API

参数


  • key : 用户给定的键值。
  • size : 申请内存的大小
  • shmflg :

返回值


成功返回共享内存的标识符;不成功返回-1,errno储存错误原因。
EINVAL 参数size小于SHMMIN或大于SHMMAX。
EEXIST 预建立key所致的共享内存,但已经存在。
EIDRM 参数key所致的共享内存已经删除。
ENOSPC 超过了系统允许建立的共享内存的最大值(SHMALL )。
ENOENT 参数key所指的共享内存不存在,参数shmflg也未设IPC_CREAT位。
EACCES 没有权限。
ENOMEM 核心内存不足。

映射共享内存 – at:attach

API


参数


  • shmid : 由shmget()函数返回的共享内存标识
  • shmaddr: 指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
  • shmflg:一组标志位,通常为0。

返回值

成功: 一个指向共享内存第一个字节的指针
失败: -1

解除映射 – dt:detach

API


参数

  • shmaddr : shmat()函数返回的地址指针

返回值

成功: 0
失败: -1

共享内存控制

API

参数

  • shmid : shmget()函数返回的共享内存标识符
  • command是要采取的操作,它可以取下面的三个值
命令说明
IPC_STAT设定 共享内存的属性
IPC_SET读取共享内存的属性
IPC_RMID删除共享内存,buf设置为NULL
SHM_LOCK锁定共享内存段( 超级用户 )。
  • 用于锁定内存,禁止内存交换。并不代表共享内存被锁定后禁止其它进程访问。
  • 其真正的意义是:被锁定的内存不允许被交换到虚拟内存中。这样做的优势在于让共享内存一直处于内存中**,从而提高程序性能**。
SHM_UNLOCK解锁共享内存段。

注意:若选择删除共享内存,第三个参数传NULL

shmid_ds 构造体

struct shmid_ds {
               struct ipc_perm shm_perm;    /* Ownership and permissions */
               size_t          shm_segsz;   /* Size of segment (bytes) */
               time_t          shm_atime;   /* Last attach time */
               time_t          shm_dtime;   /* Last detach time */
               time_t          shm_ctime;   /* Last change time */
               pid_t           shm_cpid;    /* PID of creator */
               pid_t           shm_lpid;    /* PID of last shmat(2)/shmdt(2) */
               shmatt_t        shm_nattch;  /* No. of current attaches */
               ...
           };
     struct ipc_perm {
           key_t          __key;    /* Key supplied to shmget(2) */
           uid_t          uid;      /* Effective UID of owner */
           gid_t          gid;      /* Effective GID of owner */
           uid_t          cuid;     /* Effective UID of creator */
           gid_t          cgid;     /* Effective GID of creator */
           unsigned short mode;     /* Permissions + SHM_DEST and
                                       SHM_LOCKED flags */
           unsigned short __seq;    /* Sequence number */
       };

返回值

成功: 0
失败: -1

举报

相关推荐

0 条评论