一、特点

共享内存允许多个不同的进程可以访问同一块内存。相较于其他IPC形式,具有速度快,效率高的特点,共享内存的存在降低了在大规模数据处理过程中内存的消耗。

二、创建共享内存

1、头文件


#include <sys/ipc.h>

#include <sys/shm.h>

#include <sys/types.h>

2、函数

key\_t ftok(const char *pathname, int proj\_id); 创建IPC通讯时所必需的ID值。

pathname:指定已经存在的文件名,一般是当前目录

proj\_id:子序列号,大小为1-255。

返回值:ID值,大小是文件的索引节点号前加上子序列号,例如:pathname索引节点号为0x101010,proj\_id为0x32,则ID为0x32101010。

int shmget(key\_t key, size\_t size, int shmflg); 创建或打开一块共享内存

key:标识符,每一个IPC对象与一个key相对应,大小为非0的整数

size:指定共享内存的容量

shmflg:权限标志,与open函数的mode参数类似。IPC\_CREAT,如果key标识的内存不存在,则创建。IPC\_EXCL,如果key标识的内存存在,则报错,errno为EEXIST。

返回值: 成功返回共享内存的标识符,失败返回-1。

void *shmat(int shmid, const void *shmaddr, int shmflg); 把共享内存区对象映射到调用进程的地址空间

shmid:共享内存的标识符。

shmaddr:指定共享内存连接到当前进程中的地址位置,可以为NULL,表示让系统选择共享内存的地址

shmflg:权限标志,SHM\_RND 读写,SHM\_RDONLY 只读。

返回值:成功返回共享内存的首地址,失败返回-1。

注:fork后子进程继承已连接的共享内存地址。exec后该子进程与已连接的共享内存地址自动脱离(detach)。进程结束后,已连接的共享内存地址会自动脱离(detach)

int shmdt(const void *shmaddr); 取消进程与共享内存的关联关系。

shmaddr:共享内存的首地址。

返回值:成功返回0,失败返回-1。

注:shmdt不会删除共享内存,只是将当前进程与共享内存分离。

int shmctl(int shmid, int cmd, struct shmid\_ds *buf); 操纵共享内存

shmid:共享内存标识符。

cmd:IPC\_STAT,得到共享内存的状态,把共享内存的shmid\_ds结构复制到buf中。IPC\_SET,改变共享内存的状态,把buf所指的shmid\_ds结构中的uid、gid、mode复制到共享内存的shmid\_ds结构内。IPC\_RMID,标识将要删除这片共享内存。

buf:共享内存的管理结构体

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 */
};

注:IPC\_RMID仅是将共享内存标记为删除。如果共享内存仅有当前进程连接,则直接删除。如果还有其他进程,则会将当前进程从连接中删除,并且将共享内存标识符改为0,表明其为PRIVATE状态,阻止其他进程再连接共享内存,等待其他进程断开连接后删除共享内存。

查看共享内存状态:ipcs指令

标签: int, 共享内存, 笔记, IPC, key, shm, shmid

相关文章推荐

添加新评论,含*的栏目为必填