进程间通信之2----共享内存

来源:互联网 发布:win10仿mac软件 编辑:程序博客网 时间:2024/06/08 08:36
进程间通信之2----共享内存


1、System V 共享内存机制: shmget shmat shmdt shmctl


  • 共享内存本质是一段特殊的内存区域,所有需要访问该共享区域的进程都要把该共享区域映射到本进程的地址空间中去,不同的进程可以通过对内存简单的读写,发生信息交换,从容实现通信。而这块虚拟内存的页面被每个共享进程的页表条目所引用, 同时并不需要在所有进程的虚拟内存都有相同的地址。 进程对象对于共享内存的访问通过 key(键) 来控制, 同时通过 key 进行访问权限的检查。

函数定义如下:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
key_t ftok(const char *pathname, int proj_id);    不常用。
int shmget(key_t key, int size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

     shmget接口:
  • 函数 ftok 用于创建一个关键字, 可以用该关键字关联一个共享内存段。
  • 函数 shmget 用于创建或打开一共享内存段, 该内存段由函数的第一个参数唯一创建。函数成功, 则返回一个唯一的共享内存标识号(相当于进程号, 唯一的标识着共享内存),失败返回-1。
  • 参数 key 是一个与共享内存段相关联关键字, 如果事先已经存在一个与指定关键字关联的共享内存段, 则直接返回该内存段的标识, 表示打开, 如果不存在, 则创建一个新的共享内存段。------可用于连接。
  • key 的值既可以用 ftok 函数产生,也可以是IPC_PRIVATE(用于创建一个只属于创建进程的共享内存, 主要用于父子通信) ,表示总是创建新的共享内存段;
  • 参数 size 指定共享内存段的大小, 以字节为单位;一般为页面的整数倍--一般一个页面为4k---4096个字节
  • 参数 shmflg 是一掩码合成值, 可以是访问权限值与(IPC_CREAT 或 IPC_EXCL)的
  • 合成。 IPC_CREAT 表示如果不存在该内存段, 则创建它。 IPC_EXCL 表示如果该内存
  • 段存在, 则函数返回失败结果(-1)。 如果调用成功, 返回内存段标识, 否则返回-1

      shmat接口:
  • 函数 shmat 将共享内存段映射到进程空间的某一地址。
  • 参数 shmid 是共享内存段的标识 通常应该是 shmget 的成功返回值
  • 参数 shmaddr 指定的是共享内存连接到当前进程中的地址位置。通常是 NULL, 表示让系统来选择共享内存出现的地址。
  • 参数 shmflg 是一组位标识, 通常为 0 即可。
  • 如果调用成功, 返回映射后的进程空间的首地址, 否则返回(char *)-1。

     函数 shmdt 用于将共享内存段与进程空间分离。
  • 参数 shmaddr 通常为 shmat 的成功返回值
  • 它共享内存分离并没删除它, 只是使得该共享内存对当前进程不在可用。

     函数 shmctl 是共享内存的控制函数, 可以用来删除共享内存段。
  • 参数 shmid同上。
  • 参数 cmd 是对共享内存段的操作方式, 可选为 IPC_STAT,IPC_SET,IPC_RMID。 通常为 IPC_RMID, 表示删除共享内存段。
  • 参数 buf 是表示共享内存段的信息结构体数据, 通常为 NULL。


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


  • 查看系统共享内存ipcs
  • 删除共享内存ipcrm -m shmid
原创粉丝点击