UNP(卷2:进程间通信)—— 第14章:System V共享内存区

先调用shmget,再调用shmat

对于每个共享内存区,内核维护如下信息结构 shmid_ds,<sys/shm.h>

/* Permission flag for shmget.  */
#define SHM_R       0400        /* or S_IRUGO from <linux/stat.h> */
#define SHM_W       0200        /* or S_IWUGO from <linux/stat.h> */

/* Flags for `shmat'.  */
#define SHM_RDONLY  010000      /* attach read-only else read-write */
#define SHM_RND     020000      /* round attach address to SHMLBA */
#define SHM_REMAP   040000      /* take-over region on attach */
#define SHM_EXEC    0100000     /* execution access */

/* Commands for `shmctl'.  */
#define SHM_LOCK    11      /* lock segment (root only) */
#define SHM_UNLOCK  12      /* unlock segment (root only) */

/* Data structure describing a shared memory segment.  */
struct shmid_ds
{
    struct ipc_perm shm_perm;   /* operation permission struct */
    size_t shm_segsz;           /* size of segment in bytes */
    __time_t shm_atime;         /* time of last shmat() */
#ifndef __x86_64__
    unsigned long int __glibc_reserved1;
#endif
    __time_t shm_dtime;         /* time of last shmdt() */
#ifndef __x86_64__
    unsigned long int __glibc_reserved2;
#endif
    __time_t shm_ctime;         /* time of last change by shmctl() */
#ifndef __x86_64__
    unsigned long int __glibc_reserved3;
#endif
    __pid_t shm_cpid;           /* pid of creator */
    __pid_t shm_lpid;           /* pid of last shmop */
    shmatt_t shm_nattch;        /* number of current attaches */
    __syscall_ulong_t __glibc_reserved4;
    __syscall_ulong_t __glibc_reserved5;
};
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 */
};


shmget 函数

创建一个新的共享内存区,或者访问一个已存在的共享内存区。

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key, size_t size, int shmflg);
                                               // 返回:若成功则为共享内存区对象,若出错为-1
返回值是一个称为共享内存区标识符shared memory identifier)的整数。

key:既可以是 ftok 的返回值,也可以是 IPC_PRIVATE。

size:以字节为单位指定内存区的大小。当实际操作作为创建一个新的共享内存区时,必须指定一个不为 0 的size值。如果访问一个已存在的共享内存区,那么size应为 0 。

shmflg:读写权限值的组合,可以与IPC_CREAT、IPC_EXCL。

当实际操作为创建一个新的共享内存区时,该内存区被初始化为size 字节的0。


shmat 函数

把它附接到调用进程的地址空间

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

void *shmat(int shmid, const void *shmaddr, int shmflg);
                                                         // 返回:成功则为映射区的起始地址,出错为-1 【(void *) -1】

返回值:所指定的共享内存区在调用进程内的起始地址

shmid:标识符。

shmaddr:

  • 如果shmaddr是一个空指针,那么系统替调用者选择地址。(可移植性最好)
  • 如果shmaddr 非空,那么返回地址取决于调用者是否给flag 参数指定了 SHM_RND 值。
    • 如果没有指定SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址。
    • 如果过指定了SHM_RND,那么相应的共享内存区附接到由shmaddr参数指定的地址向下舍入一个SHMLBA常值。LBA代表“低端边界地址”(lower boundary Address)。


shmdt 函数

当一个进程完成某个共享内存区的使用时,它可以调用 shmdt断接这个内存区并不删除所指定的共享内存区

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

int shmdt(const void *shmaddr);
                                  // 返回:成功则为0,出错为-1
当一个进程终止时,它当前附接着的共享内存区都自动断接掉。


shmctl 函数

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
                                                     // 返回:成功0,出错-1

/* Control commands for `msgctl', `semctl', and `shmctl'.  */
#define IPC_RMID    0       /* Remove identifier.  */
#define IPC_SET     1       /* Set `ipc_perm' options.  */
#define IPC_STAT    2       /* Get `ipc_perm' options.  */
IPC_RMID:从系统中删除由shmid标识的共享内存区并拆除它。

IPC_SET:给所指定的共享内存区设置其 shmid_ds 结构的以下三个成员:shm_perm.uid,shm_perm.gid和shm_perm.mode,他们的值来自buff参数指向的结构中的相应成员。shm_ctime的值也用当前时间替换。

IPC_STAT :(通过buff参数)向调用者返回所指定共享内存区当前的 shmid_ds 结构,将其保存在buf所指向的缓冲区。














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章