linux共享内存

1.定义key

生成一个任意不重复的key作为整个系统生命周期的内存标识;
例如ftok();根据特定序列或者文件名生成唯一key;也可以手动指定

2.开辟共享内存:

shmget(key,size,flag);

key:标识
size: 共享内存大小,单位byte
flag:权限位,一般创建时|IPC_CREAT,如果|ICP_EXCL则只能新建,已有就报错
返回值:shmid, 此ID作用于内核存续生命周期的共享内存标识

2.1打开已有的共享内存

shmget(key,0,0)

key:标识
返回值:shmid

2.2获取共享内存属性

定义一个 struct shmid_ds 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 */
       ...
  };
shmctl(shmid,IPC_STAT,buf);

此时这个buf.shm_segsz就是获取的共享内存大小

3.映射共享内存地址到进程地址空间

用户进程的地址是通过页表映射到物理地址的,共享内存的地址也需要映射后才能被用户进程调用

void *pshm
pshm=shmat(shmid,NULL,SHM_RND);

shmid:如上获取
NULL:这里如果有权限,可以自己指定虚拟地址
SHM_RND:还可以设定SHM_RDONLY只读,这里是读写权限

4.使用完毕后删除映射(内存还在,内核管理在)

shmdt(pshm)

这里pshm是之前映射好的地址指针。

5.删除共享内存

shmctl(shmid,IPC_SET,IPC_RMID)

shmid:如上2获取
IPC_SET:这个上面用IPC_STAT获取内存信息,这里IPC_SET就是设置内存信息,权限充足的情况下,也可以通过定义好的信息结构体来设定详细的共享内存结构
IPC_RMID:标志位删除,不会立即删除,最后一个引用该内存的进程退出后由内核删除。

你可能感兴趣的:(C/C++,linux)