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所指向的緩衝區。














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