shmat 和 shmdt

https://linux.die.net/man/2/shmat
shmat, shmdt  共享内存的操作

概要
#include <sys/types.h>#include <sys/shm.h>

void *shmat(int shmid, const void *shmaddr, int shmflg);

int shmdt(const void *shmaddr);

描述

 shmat()把由shmid标识的共享内存关联到调用进程的地址空间。关联地址由 shmaddr指定,遵循如下规则的其中之一。

  • 如果 shmaddr 不是 NULL, 并且shmflg指定了SHM_RND, 关联的地址与shmaddr 向下舍入到最近的SHMLBA的倍数。否则, shmaddr必须是 page-aligned 地址。
  • 如果shmflg中设置了SHM_RDONLY,则该共享地址段是只读的,当前调用进程必须只设置读权限。如果shmflg中没有设置SHM_RDONLY,则该共享地址段是可读写的, 该进程必须设置读写权限。对于只写共享内存段没有指定和说明。
  • shmflg中可能会设置SHM_REMAP  (只有linux版本支持), 来标识共享内存段的映射可以替换替换已经存在的映射,起始地址是shmaddr, 连续共享内存段大小的内存。通常情况下,如果该地址范围已经存在一个映射,会返回EINVAL 错误。这种情况下,shmaddr不能是NULL。
  • 调用进行的brk(2) 值不能被attach操作改变。当进程退出时,共享内存段会自动的detach。相同的共享内存段可能被attach成只读或读写的,或多个,在进程的地址空间内。

成功的shmat()调用会更新共享内存段所关联的shmid_ds 结构体的成员,如下所示:

  • shm_atime,设置成当前时间
  • shm_lpid,设置成当前调用进程的process-ID。
  • shm_nattch, 加1.

shmdt()  是从调用进程的地址空间中detach  shmaddr指定的共享内存段所在的地址。shmat的逆操作。to-be-detached 的共享内存段必须是由shmat()调用返回的shmaddr。

一个成功的shmdt()调用会更新共享内存段所关联的shmid_ds 结构体的成员,如下所示:

  • shm_atime,设置成当前时间
  • shm_lpid,设置成当前调用进程的process-ID。
  • shm_nattch, 减1.如果变成了0, 共享内存段被标识要进行deletion,该共享内存段会被删除。fork(2)的子进程会继承关联的共享内存段。
  • 在 execve(2)调用之后,所有关联的共享内存段会从该进程中detach。
  • _exit(2)调用后,该进程关联的所有共享内存段都会被detach。

返回值

如果shmat()成功,返回共享内存段在该进程中关联地址;如果出错,返回(void *) -1, errno 来标识出错的原因。

如果shmdt()成功,则返回0;否则,返回(void *) -1, errno 来标识出错的原因。

shmat()的出错码

  • EACCES, the calling process does not have the required permissions for the requested attach type, and does not have the CAP_IPC_OWNER capability.
  • EIDRM, shmid points to a removed identifier.
  • EINVAL, Invalid shmid value, unaligned (i.e., not page-aligned and SHM_RND was not specified) or invalid shmaddr value, or can't attach segment at shmaddr, or SHM_REMAP was specified and shmaddr was NULL.
  • ENOMEM, Could not allocate memory for the descriptor or for the page tables.

shmdt() 的出错码

  • EINVAL, There is no shared memory segment attached at shmaddr; or, shmaddr is not aligned on a page boundary.

说明:

调用shmat()时,最好设置shmaddr为NULL,这样共享内存段的关联会具有可移植性。值得注意的是,这种方式进行的共享内存段的关联,不同的进程会关联到不同的地址。因此,任何一个保持共享内存的指针必须是相对地址(典型的是,从共享内存段的起始地址开始)而不是绝对地址。

下面的系统参数会影响到shmat()操作:

  • SHMLBA:Segment low boundary address multiple. Must be page aligned. For the current implementation the SHMLBA value is PAGE_SIZE.
  • The implementation places no intrinsic limit on the per-process maximum number of shared memory segments (SHMSEG).

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值