SHMGET - Linux手册页

时间:2019-08-20 17:59:25  来源:igfitidea点击:

Linux程序员手册 第2部分
更新日期: 2020-04-11

名称

shmget-分配系统V共享内存段

语法

#包括
#包括

int shmget(key_t键,size_t大小,int shmflg);

说明

shmget()返回与自变量键的值关联的System V共享内存段的标识符。它既可以用于获取先前创建的共享内存段的标识符(当shmflg为零且键的值不为IPC_PRIVATE时),也可以用于创建新集合。

如果密钥的值为IPC_PRIVATE或密钥不是IPC_PRIVATE,并且不存在与密钥对应的共享内存段,并且指定了IPC_CREAT,则创建一个新的共享内存段,其大小等于size的值四舍五入为PAGE_SIZE的倍数。在shmflg中。

如果shmflg同时指定了IPC_CREAT和IPC_EXCL,并且密钥已经存在共享内存段,则shmget()会失败,并且errno设置为EEXIST。 (这类似于组合open_(2)的O_CREAT | O_EXCL的效果。)

值shmflg包含:

IPC_CREAT
创建一个新的细分。如果未使用此标志,则shmget()将查找与key关联的段,并检查用户是否有权访问该段。
IPC_EXCL
该标志与IPC_CREAT一起使用,以确保此调用创建该段。如果该段已经存在,则调用失败。
SHM_HUGETLB(since Linux 2.6)
使用"大页面"分配细分。有关更多信息,请参见Linux内核源文件Documentation / admin-guide / mm / hugetlbpage.rst。
SHM_HUGE_2MB, SHM_HUGE_1GB(since Linux 3.8)
与SHM_HUGETLB结合使用,以在支持多个hugetlb页面大小的系统上选择其他的hugetlb页面大小(分别为2 MB和1 GB)。
更一般地,可以通过以偏移SHM_HUGE_SHIFT的六位编码所需页面大小的以2为底的对数来配置所需的巨大页面大小。因此,以上两个常量定义为:
#define SHM_HUGE_2MB    (21 << SHM_HUGE_SHIFT)
#define SHM_HUGE_1GB    (30 << SHM_HUGE_SHIFT)
有关其他一些详细信息,请参见mmap(2)中有关类似命名的常量的讨论。
SHM_NORESERVE(since Linux 2.6.15)
该标志的作用与mmap(2)MAP_NORESERVE标志相同。不要为此段保留交换空间。当保留交换空间时,可以保证可以修改段。如果没有保留交换空间,则在没有可用物理内存的情况下,可能会在写入时得到SIGSEGV。另请参阅proc(5)中有关文件/ proc / sys / vm / overcommit_memory的讨论。

除了上述标志之外,shmflg的最低9位还指定授予所有者,组和其他用户的权限。这些位与open(2)的mode参数具有相同的格式和相同的含义。当前,系统未使用执行权限。

创建新的共享内存段时,其内容初始化为零值,并且其相关的数据结构shmid_ds(请参见shmctl(2))初始化如下:

*
shm_perm.cuid和shm_perm.uid设置为调用过程的有效用户ID。
*
shm_perm.cgid和shm_perm.gid设置为调用进程的有效组ID。
*
将shm_perm.mode的最低有效9位设置为shmflg的最低有效9位。
*
shm_segsz设置为size的值。
*
shm_lpidshm_nattch,shm_atime和shm_dtime设置为0。
*
shm_ctime设置为当前时间。

如果共享内存段已经存在,则将验证权限,并进行检查以查看是否将其标记为销毁。

返回值

成功后,将返回有效的共享内存标识符。如果出错,则返回-1,并且将errno设置为指示错误。

错误说明

失败时,errno设置为以下之一:

EACCES
用户无权访问共享内存段,并且在管理其IPC名称空间的用户名称空间中不具有CAP_IPC_OWNER功能。
EEXIST
在shmflg中指定了IPC_CREAT和IPC_EXCL,但是密钥已经存在共享内存段。
EINVAL
将创建一个新的段,并且其大小小于SHMMIN或大于SHMMAX。
EINVAL
存在给定键的段,但是大小大于该段的大小。
ENFILE
已达到系统范围内打开文件总数的限制。
ENOENT
给定密钥不存在任何段,并且未指定IPC_CREAT。
ENOMEM
无法为段开销分配内存。
ENOSPC
已使用所有可能的共享内存ID(SHMMNI),否则分配请求大小的段将导致系统超出系统范围的共享内存限制(SHMALL)。
EPERM
指定了SHM_HUGETLB标志,但是没有给调用方特权(没有CAP_IPC_LOCK功能)。

遵循规范

POSIX.1-2001,POSIX.1-2008,SVr4。

SHM_HUGETLB和SHM_NORESERVE是Linux扩展。

备注

在Linux或任何版本的POSIX上,都不需要包含和。但是,一些旧的实现需要包含这些头文件,并且SVID也记录了这些头文件。打算移植到这样的旧系统的应用程序可能需要包括这些头文件。

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

Shared memory limits

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

SHMALL
系统范围内共享内存总量的限制,以系统页面大小为单位进行度量。
在Linux上,可以通过/ proc / sys / kernel / shmall读取和修改此限制。从Linux 3.16开始,此限制的默认值为:
ULONG_MAX-2 ^ 24
此值的效果(适用于32位和64位系统)对分配没有任何限制。选择该值而不是ULONG_MAX作为默认值是为了防止在某些情况下历史应用程序仅在不先检查其当前值的情况下就提高了现有限制。如果将限制设置为ULONG_MAX,则此类应用程序将导致该值溢出。
从Linux 2.4到Linux 3.15,此限制的默认值为:
SHMMAX / PAGE_SIZE *(SHMMNI / 16)
如果未修改SHMMAX和SHMMNI,则将该公式的结果乘以页面大小(以字节为单位的值)将得出8 GB的值,作为所有共享内存段使用的总内存的限制。
SHMMAX
共享内存段的最大大小(以字节为单位)。
在Linux上,可以通过/ proc / sys / kernel / shmmax读取和修改此限制。从Linux 3.16开始,此限制的默认值为:
ULONG_MAX-2 ^ 24
此值的效果(适用于32位和64位系统)对分配没有任何限制。有关为何使用此默认值(而不是ULONG_MAX)的讨论,请参见SHMALL的描述。
从Linux 2.2到Linux 3.15,此限制的默认值为0x2000000(32 MB)。
由于不可能仅映射共享内存段的一部分,因此虚拟内存量对可用段的最大大小设置了另一个限制:例如,在i386上,可以映射的最大段的大小约为2.8。 GB,在x86-64上,最大限制为127 TB。
SHMMIN
共享内存段的最小大小(以字节为单位):与实现有关(当前为1个字节,尽管PAGE_SIZE是有效的最小大小)。
SHMMNI
系统范围内共享内存段数的限制。在Linux 2.2中,此限制的默认值为128;默认值为128。从Linux 2.4开始,默认值为4096。
在Linux上,可以通过/ proc / sys / kernel / shmmni读取和修改此限制。

对于每个进程的共享内存段最大数量(SHMSEG),该实现没有特定限制。

Linux notes

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

BUGS

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

示例

请参见shmop(2)。

另外参见

memfd_create(2),shmat(2),shmctl(2),shmdt(2),ftok(3),功能(7),shm_overview(7),sysvipc(7)

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/