shmget() - Unix,Linux 系统调用
Tutorials Point


  Unix 初学者指南
  Unix Shell 编程
  高级 Unix
  Unix 有用参考
  Unix 有用资源
  精选阅读

版权所有 © 2014 tutorialspoint



  首页     参考     讨论论坛     关于 TP  

shmget() - Unix,Linux 系统调用


previous next AddThis Social Bookmark Button

广告

名称

shmget - 分配共享内存段

语法

#include <sys/ipc.h>

#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);

描述

shmget() 返回与参数 key 的值关联的共享内存段的标识符。如果 key 的值为 IPC_PRIVATE,则创建一个新的共享内存段,其大小等于 size 的值向上舍入到 PAGE_SIZE 的倍数;或者如果 key 不为 IPC_PRIVATE,并且不存在与 key 对应的共享内存段,并且在 shmflg 中指定了 IPC_CREAT,则创建一个新的共享内存段。

如果 shmflg 同时指定了 IPC_CREATIPC_EXCL,并且对于 key 已经存在共享内存段,则 shmget() 失败,并将 errno 设置为 EEXIST。(这类似于 open(2) 的组合 O_CREAT | O_EXCL 的效果。)

shmflg 的值由以下组成:

标签描述
SHM_HUGETLB 用于为共享内存分配 HUGETLB 页面。IPC_CREAT 用于创建新的段。如果不使用此标志,则 shmget() 将找到与 key 关联的段,并检查用户是否有权访问该段。
IPC_EXCL IPC_CREAT 一起使用,以确保如果段已存在则失败。
mode_flags (最低有效 9 位)指定授予所有者、组和世界的权限。这些位具有相同的格式和相同的含义,与 open(2) 的 mode 参数相同。目前,系统不使用执行权限。
SHM_HUGETLB(自 Linux 2.6 起)
 使用“巨型页面”分配段。有关更多信息,请参阅内核源文件 Documentation/vm/hugetlbpage.txt
SHM_NORESERVE(自 Linux 2.6.15 起)
 此标志与 mmap(2) 的 MAP_NORESERVE 标志具有相同的用途。不要为该段保留交换空间。当保留交换空间时,可以保证可以修改该段。当不保留交换空间时,如果无法获得物理内存,则写入时可能会收到 SIGSEGV。另请参阅 proc(5) 中 /proc/sys/vm/overcommit_memory 文件的讨论。
创建新的共享内存段时,其内容将初始化为零值,其关联的数据结构 shmid_ds(参见 shmctl(2))将按如下方式初始化:
标签描述
shm_perm.cuidshm_perm.uid 设置为调用进程的有效用户 ID。
shm_perm.cgidshm_perm.gid 设置为调用进程的有效组 ID。
shm_perm.mode 的最低有效 9 位设置为 shmflg 的最低有效 9 位。
shm_segsz 设置为 size 的值。
shm_lpidshm_nattchshm_atimeshm_dtime 设置为 0。
shm_ctime 设置为当前时间。
如果共享内存段已存在,则会验证权限,并检查它是否已标记为要销毁。

系统调用

标签描述
fork() fork() 之后,子进程继承附加的共享内存段。
exec() exec() 之后,所有附加的共享内存段都将分离(不会销毁)。
exit() exit() 时,所有附加的共享内存段都将分离(不会销毁)。

返回值

成功时返回有效的段标识符 shmid,错误时返回 -1。

错误

失败时,errno 将设置为以下之一:
标签描述
EACCES 用户无权访问共享内存段,并且没有 CAP_IPC_OWNER 权限。
EEXIST 指定了 IPC_CREAT | IPC_EXCL,并且段存在。
EINVAL 要创建一个新的段,并且 size < SHMMINsize > SHMMAX;或者不创建新的段,具有给定键的段存在,但 size 大于该段的大小。
ENFILE 已达到系统打开文件的总数限制。
ENOENT 对于给定的 key 不存在段,并且未指定 IPC_CREAT
ENOMEM 无法为段开销分配内存。
ENOSPC 所有可能的共享内存 ID 都已被占用(SHMMNI),或者分配请求的 size 大小的段会导致系统超过共享内存的系统范围限制(SHMALL)。
EPERM 指定了 SHM_HUGETLB 标志,但调用者没有特权(没有 CAP_IPC_LOCK 权限)。

备注

IPC_PRIVATE 不是标志字段,而是 key_t 类型。如果将此特殊值用于 key,则系统调用将忽略 shmflg 的最低有效 9 位以外的所有内容,并创建一个新的共享内存段(成功时)。

以下关于共享内存段资源的限制会影响 shmget() 调用:

标签描述
SHMALL 共享内存页面的系统范围最大值(在 Linux 上,可以通过 /proc/sys/kernel/shmall 读取和修改此限制)。
SHMMAX 共享内存段的最大大小(以字节为单位):策略相关(在 Linux 上,可以通过 /proc/sys/kernel/shmmax 读取和修改此限制)。
SHMMIN 共享内存段的最小大小(以字节为单位):实现相关(目前为 1 字节,尽管 PAGE_SIZE 是有效最小大小)。
SHMMNI 共享内存段的系统范围最大数量:实现相关(目前为 4096,在 Linux 2.3.99 之前为 128;在 Linux 上,可以通过 /proc/sys/kernel/shmmni 读取和修改此限制)。
实现对每个进程的共享内存段的最大数量(SHMSEG)没有特定限制。

缺陷

名称选择 IPC_PRIVATE 可能是不幸的,IPC_NEW 将更清楚地显示其功能。

符合标准

SVr4、POSIX.1-2001。

Linux 备注

在版本 2.3.30 之前,Linux 会在计划删除的共享内存段上返回 shmget() 的 EIDRM。

SHM_HUGETLB 是一个非可移植的 Linux 扩展。

参见



previous next Printer Friendly

广告


  

广告



广告