共享内存区的使用

共享内存区:

共享内存区时IPC形式中最快的。由于当共享内存区映射到共享它的进程的地址空间,这些进程间
数据的传递就不在涉及内核(进程不在经过执行任何进入内核的系统调用来传递数据)。

与其余IPC形式相比,进程经过共享内存区传递数据的步骤:

 

注意:默认状况下,经过fork()派生的子进程并不与其父进程共享内存区

使用共享内存区时所需的函数:

mmap()函数:

为什么使用mmap()函数:
1.使用普通文件以提供内存映射I/O
2.使用特殊文件以提供匿名内存映射
3.使用shm_open以提供无亲缘关系进程间的Posix共享内存区
#include <sys/mman.h>

// 将一个文件或一个Posix共享内存区对象映射到调用进程的地址空间
// 成功返回被映射区的起始地址,出错返回MAP_FAILED
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
// addr:能够指定描述符fd应被映射到的进程内空间的起始地址(一般addr被指定为NULL,让内核本身选择起始地址)
// len: 映射到调用进程地址空间的字节数,它从被映射文件开头其第offset个字节出开始算
// prot:指定内存映射区保护(PROT_READ可读、PROT_WRITE可写、PROT_EXEC可执行、PROT_NONE不可访问)
// flags:指定进程对被映射数据所作的修改是否对共享该对象的其余进程共享,其值以下:
//     必须为MAP_SHARED(共享)或MAP_PRIVATE(私有)之一,能够或上(|)MAP_FIXED(准确的解释addr值)
//     共享即意味着该修改改变该共享对象的底层支撑对象(如某个文件,该文件被映射,此文件为底层支撑对象)
// fd: 被映射的文件的描述符
// offset: 偏移量(通常该值为0)
// 为了可移植考虑,通常将addr指定为空指针,而且不指定MAP_FIXED

munmap()函数:

#include <sys/mman.h>

// 删除一个映射关系、
// 成功返回0,出错返回-1
int munmap(void *addr, size_t len);
// addr:是由mmap()返回的地址
// len:映射区大小

msync()函数:

官方说明html

#include <sys/mman.h>

// 使得硬盘中的文件与内存映射区内容一致,使用msync()执行同步
// 成功返回0,出错返回-1
int msync(void *addr, size_t len, int flags);
/*
关于addr和len参数的说明
The addr argument is the address of the first page of mapped memory to be synchronized.
The address must be on a page boundary, but need not be the first byte of the entire 
area mapped to a file. 
The len argument specifies the number of bytes of memory to be synchronized. If the length
does not specify an integral number of pages, it is rounded up to do so. The length need
not specify the entire area of mapped memory. 
*/
// flags: 取值为MS_ASYNC(异步写)或MS_SYNC(同步写)之一,还能够或上MS_INVALIDATE()

Posix共享内存区:

Posix提供的两种在无亲缘关系的进程间共享内存区的方法:
1.内存映射文件:由open()打开某个文件,再由mmap()将获得的描述符映射到当前进程地址空间中
的一个文件。
2.共享内存区对象:有shm_open()打开一个Posix IPC名字(多是文件系统中的一个路径名),所返
回的描述符有mmap()映射到当前进程的地址空间。

shm_open()函数:

#include <sys/mman.h>

// 建立一个新的共享内存区对象,或打开一个已存在的共享内存区对象
// 成功返回非负描述符,出错返回-1
int shm_open(const char *name, int oflag, mode_t mode);
// name: Posix IPC名字,name参数随后也做为但愿共享该内存区的任何其余进程使用
// oflag: 该参数必须含有O_RDONLY(只读)或O_RDWR(读写),能够或上O_CREAT,O_EXCL,O_TRUNC
// 若 oflag = O_RDWD | O_TRUNC,且所需共享内存区对象已存在,那么它的长度被截短成0
// mode:权限位,在没有指定O_CREAT时mode能够为0,当指定了O_CREAT后,mode参数必须指定

建立新的IPC对象所用的mode常值:
S_IRUSR    用户(属主)读
S_IWUSR    用户(属主)写
S_IRGRP    属组读
S_IWGRP    属组写
S_IROTH    其余用户读
S_IWOTH    其余用户写数据结构

shm_unlink()函数:

#include <sys/mman.h>

// 删除一个共享内存区对象名字,防止后续的open调用成功(与unlink、ma_unlink、sem_unlink相似)
// 成功返回0,出错返回-1
int shm_unlink(const char *name);

System V共享内存区:

与Posix共享内存区相似,只不过将shm_open()、mmap()调用换成了shmget()、shmat()调用sem_post

shmid_ds结构:

#include <sys/shm.h>

// 内核为每一个共享内存区维护的信息结构
struct shmid_ds{
    struct ipc_perm shm_perm;
    size_t          shm_segsz;
    pid_t           shm_lpid;
    pid_t           shm_cpid;
    shmatt_t        shm_nattch;
    shmat_t         shm_cnattch;
    time_t          shm_atime;
    time_t          shm_dtime;
    time_t          shm_ctime;
};

shmget()函数:

#include <sys/shm.h>

// 建立一个新的共享内存区,或访问一个已存在的共享内存区
// 成功返回共享内存区标识符,出错返回-1
int shmget(key_t key, size_t size, int oflag);
// key:System V IPC名字,能够是ftok()返回值,也能够是IPC_PRIVATE
// size:指定内存区大小,单位为字节
//    当建立一个新的共享内存区时,该内存区被初始化为size字节的0
//    当访问一个已存在的共享内存区时,size应为0
// oflag:同shm_open()的oflag参数

shmat()函数:

#include <sys/shm.h>

// 在shmget()打开一个共享内存区后,shmat()将其附接到调用进程的地址空间
// 成功返回映射区起始地址,出错返回-1
void *shmat(int shmid, const void *shmaddr, int flag);
// shmid: 有shmget()返回的标识符
// shmaddr: 为空时,系统替调用者选择指定共享内存区在调用进程内的起始地址
//          非空时,返回地址取决于flag参数
// flag: 指定了SHM_RND时,相应共享内存区附接到由shmaddr参数指定的地址
//       没有指定SHM_RND,相应共享内存区附接到由shmaddr参数指定的地址向下舍入一个SHMLBA常值
// 默认状况下,只要调用进程具备某个共享内存区的读写权限,它附接到该内存区后就能读写该内存区
// flag指定为SHM_RDONLY时,限定只读访问共享内存区

shmdt()函数:

#include <sys/shm.h>

// 断接某个已附接的共享内存区
// 成功返回0,出错返回-1
int shmdt(const void *shmaddr);
// shmaddr: 某个已附接的共享内存区的起始地址

shmctl()函数:

#include <sys/shm.h>

// 对共享内存区的各类操做
// 成功返回0,出错返回-1
int shmctl(int shmid, int cmd, struct shmid_ds *buff);
// shmid: 共享内存区标识符
// cmd:操做命令
// buff:共享内存区信息结构的一个指针

cmd命令:
IPC_RMID:将由shmid指定的共享内存区从系统删除,并释放或回收期对应的数据结构
IPC_SET:经过buff指向的结构,设置指定共享内存区的shmid_ds结构的shm_perm.uid shm_perm.gid shm_perm.mode
IPC_STAT: 经过buff返回指定共享内存区当前的shmid_ds结构app

相关文章
相关标签/搜索