共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式。
不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用 C语言 malloc()分配的内存一样。两个进程使用共享内存通信机制。
POSIX 共享内存区涉及四个主要步骤:
指定一个名字参数调用 shm_open, 以创建一个新的共享内存区对象(或打开一个
以存在的共享内存区对象);
调用 mmap 把这个共享内存区映射到调用进程的地址空间;
调用 munmap() 取消共享内存映射;
调用 shm_unlink()函数删除共享内存段。
在编译 POSIX 共享内存应用程序时需要加上-lrt 参数。
打开或创建一个共享内存区
shm_open()函数用来打开或者创建一个共享内存区, 两个进程可以通过给 shm_open()函数传递相同的名字以达到操作同一共享内存的目的。
它的原型如下:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int shm_open(const char *name, int oflag, mode_t mode);
函数成功返回创建或打开的共享内存描述符,与文件描述符相同作用,供后续操作使用,失败返回-1。
参数 name 为指定创建的共享内存的名称,其它进程可以根据这个名称来打开共享内存;
参数 oflag 为以下值的或值:
O_RDONLY:共享内存以只读方式打开;
O_RDWR:共享内存以可读写方式打开;
O_CREAT:共享内存不存在才创建;
O_EXCL:如果指定了 O_CREAT,但共享内存已经存在时返回错误;
O_TRUNC:如果共享内存已存在则将大小设置为 0;
参数 mode 只有指定 O_CREAT 才有效指出,指出共享内存的权限,与 open()函数类似。
删除共享内存
参数 oflag 为以下值的或值:
O_RDONLY:共享内存以只读方式打开;
O_RDWR:共享内存以可读写方式打开;
O_CREAT:共享内存不存在才创建;
O_EXCL:如果指定了 O_CREAT,但共享内存已经存在时返回错误;
O_TRUNC:如果共享内存已存在则将大小设置为 0;
参数 mode 只有指定 O_CREAT 才有效指出,指出共享内存的权限,与 open()函数类似。
删除共享内存
当使用完共享内存后,需要将其删除,以便释放系统资源,可通过 shm_unlink()函数完成。
shm_unlink()函数原型如下:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
int shm_unlink(const char *name);
函数成功返回 0,否则返回-1。
参数 name 为共享内存的名字。
设置共享内存大小
创建一个共享内存后,默认大小为 0,所以需要设置共享内存大小。
ftruncate()函数可用来调整文件或者共享内存的大小,它的原型如下:
#include <unistd.h>
#include <sys/types.h>
int ftruncate(int fd, off_t length);
函数成功返回 0,失败返回-1。
参数 fd 为需要调整的共享内存或者文件, length 为需要调整的大小。