shmget() -- 创建共享内存

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);


key_t key
-----------------------------------------------
    key标识共享内存的键值: 0/IPC_PRIVATE。 当key的取值为IPC_PRIVATE,则函数shmget()将建立一块新的共享内存;若是key的取值为0,而参数shmflg中设置了IPC_PRIVATE这个标志,则一样将建立一块新的共享内存。
    在IPC的通讯模式下,不论是使用消息队列仍是共享内存,甚至是信号量,每一个IPC的对象(object)都有惟一的名字,称为“键”(key)。经过 “键”,进程可以识别所用的对象。“键”与IPC对象的关系就如同文件名称之于文件,经过文件名,进程可以读写文件内的数据,甚至多个进程可以共用一个文 件。而在IPC的通信模式下,经过“键”的使用也使得一个IPC对象能为多个进程所共用。
    Linux系统中的全部表示System V中IPC对象的数据结构都包括一个ipc_perm结构,其中包含有IPC对象的键值,该键用于查找System V中IPC对象的引用标识符。若是不使用“键”,进程将没法存取IPC对象,由于IPC对象并不存在于进程自己使用的内存中。
    一般,都但愿本身的程序能和其余的程序预先约定一个惟一的键值,但实际上并非总可能的成行的,由于本身的程序没法为一块共享内存选择一个键值。所以,在 此把key设为IPC_PRIVATE,这样,操做系统将忽略键,创建一个新的共享内存,指定一个键值,而后返回这块共享内存IPC标识符ID。而将这个 新的共享内存的标识符ID告诉其余进程能够在创建共享内存后经过派生子进程,或写入文件或管道来实现。


int size(单位字节Byte)
-----------------------------------------------
    size是要创建共享内存的长度。全部的内存分配操做都是以页为单位的。因此若是一段进程只申请一块只有一个字节的内存,内存也会分配整整一页(在 i386机器中一页的缺省大小PACE_SIZE=4096字节)这样,新建立的共享内存的大小其实是从size这个参数调整而来的页面大小。即若是 size为1至4096,则实际申请到的共享内存大小为4K(一页);4097到8192,则实际申请到的共享内存大小为8K(两页),依此类推。


int shmflg
-----------------------------------------------
    shmflg主要和一些标志有关。其中有效的包括IPC_CREAT和IPC_EXCL,它们的功能与open()的O_CREAT和O_EXCL至关。
    IPC_CREAT   若是共享内存不存在,则建立一个共享内存,不然打开操做。
    IPC_EXCL    只有在共享内存不存在的时候,新的共享内存才创建,不然就产生错误。

    若是单独使用IPC_CREAT,shmget()函数要么返回一个已经存在的共享内存的操做符,要么返回一个新建的共享内存的标识符。若是将 IPC_CREAT和IPC_EXCL标志一块儿使用,shmget()将返回一个新建的共享内存的标识符;若是该共享内存已存在,或者返回-1。 IPC_EXEL标志自己并无太大的意义,可是和IPC_CREAT标志一块儿使用能够用来保证所得的对象是新建的,而不是打开已有的对象。对于用户的读 取和写入许可指定SHM_RSHM_W,(SHM_R>3)和(SHM_W>3)是一组读取和写入许可,而(SHM_R>6)和(SHM_W>6)是全局读取和写入许可。


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


struct shmid_ds
-----------------------------------------------
    shmid_ds数据结构表示每一个新建的共享内存。当shmget()建立了一块新的共享内存后,返回一个能够用于引用该共享内存的shmid_ds数据结构的标识符。

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 */
        __kernel_time_t    shm_dtime;     /* last detach time */
        __kernel_time_t    shm_ctime;     /* last change time */
        __kernel_ipc_pid_t shm_cpid;      /* pid of creator */
        __kernel_ipc_pid_t shm_lpid;      /* pid of last operator */
        unsigned short     shm_nattch;    /* no. of current attaches */
        unsigned short     shm_unused;    /* compatibility */
        void               *shm_unused2; /* ditto - used by DIPC */
        void               *shm_unused3; /* unused */
    };


struct ipc_perm
-----------------------------------------------
    对于每一个IPC对象,系统共用一个struct ipc_perm的数据结构来存放权限信息,以肯定一个ipc操做是否能够访问该IPC对象。

    struct ipc_perm {
        __kernel_key_t   key;
        __kernel_uid_t   uid;
        __kernel_gid_t   gid;
        __kernel_uid_t   cuid;
        __kernel_gid_t   cgid;
        __kernel_mode_t mode;
        unsigned short   seq;
};html

相关文章
相关标签/搜索