前言
简介
共享内存是可被多个进程读取的内存。用特殊的系统调用分配和释放内存并设置权限;通过一般的读写操作读写内存段中的数据。使用共享内存是进程间进行本地通信的方法之一。最重要的是,它能够较少由于I/O操作带来的开销。
适用范围
它适用于任何类型的协作,尤其适合需要安全性的情况。
来源
共享内存并非从某一个进程中划分出来的,进程的内存总是私有的,而共享内存是从系统的空闲内存池中分配的,希望访问它的每个进程连接它。这个连接过程称为映射,它给共享内存段分配每个进程的地址空间中的本地地址。
API
有两套共享内存 API:POSIX API 和比较老(但是仍然有效)的 System V API。下面做了一个简单的对比。
POSIX API | system V API | |
---|---|---|
获取共享内存ID | int shm_open(const char *name, int oflag, mode_t mode); | int shmget(key_t key, size_t size, int shmflg); |
映射内存 | void mmap(void addr, size_t length, int prot, int flags, int fd, off_t offset); | void shmat(int shmid, const void shmaddr, int shmflg); |
解除映射 | int munmap(void *addr, size_t length); | void shmat(int shmid, const void shmaddr, int shmflg); |
因为 POSIX 是 UNIX 和 Linux® 及其衍生系统上的公认标准,所以下面介绍POSIX API。
POSIX 为创建、映射、同步和取消共享内存段提供五个入口点:
- int shm_open(const char *name, int oflag, mode_t mode);
功能描述:创建或者打开已经存在的共享内存块
返回值:成功返回文件描述符,失败返回-1
name:共享内存区的名称
oflag:标志位,可选择读,写等
mode:权限位 int shm_unlink(const char *name);
功能描述:
根据(shm_open() 返回的)文件描述符,删除共享内存段。实际上,这个内存段直到访问它的所有进程都退出时才会删除,这与在 UNIX 中删除文件很相似。但是,调用 shm_unlink() (通常由原来创建共享内存段的进程调用)之后,其他进程就无法访问这个内存段了。
返回值:失败返回-1
name:共享内存区名称void mmap(void addr, size_t length, int prot, int flags,int fd, off_t offset);
功能描述:把共享内存段映射到进程的内存。这个系统调用需要 shm_open() 返回的文件描述符,它返回指向内存的指针。在某些情况下,还可以把一般文件或另一个设备的文件描述符映射到内存。
返回值:成功返回映射区地址,失败返回-1
addr:映射区的开始地址,设置为0时表示由系统决定映射区的起始地址
length:映射区的长度,以字节为单位。
prot:内存保护标志
flags:标志位
fd:文件描述符
offset:被映射对象内容的起点。void mmap(void addr, size_t length, int prot, int flags, int fd, off_t offset);
功能描述:作用与 mmap() 相反。
返回值:成功返回0,失败返回-1- int msync(void *addr, size_t length, int flags);
功能描述:用来让共享内存段与文件系统同步 — 当把文件映射到内存时,这种技术有用。
返回值:成功返回0,失败返回-1
addr:文件映射到进程空间的地址;
length:映射空间的大小;
flags:刷新的参数设置,可以取值MS_ASYNC/ MS_SYNC/ MS_INVALIDATE
fd:文件描述符
offset:被映射对象内容的起点使用过程
1.创建内存段(shm_open)
2.映射内存段(mmap)
3.使用
4.删除(munmap(),shm_unlink)
程序示例
下面的程序简单说明了共享内存的使用方法。在开辟一片共享内存区域后,子进程写入数据,而父进程在子进程写入数据后,将数据读出,并打印。具体代码如下:
1 | /*================================================================ |
编译:
1 | gcc -g mmap.c -lrt -o mmap |
运行:
1 | child wrote hello world |
总结
本文简单介绍了共享内存以及简单使用。后面将会有更多的介绍。