八, Linux 应用编程之六: 共享内存
共享内存是进程间通信的一种方法. 共享内存实际上是两个进程打开同一段内存, 并都映射到进程地址中, 这样就类似于 malloc 了一个内存 * ptr, 进程 A 往这个地址中写数据, 进程 B 就可以从这个地址读取到进程 A 写进去的数据.
使用共享内存有以下步骤:
shm_open(): 打开或创建一个共享内存.
ftruncate(): 设置共享内存的大小.
mmap(): 将共享内存映射到当前进程的地址空间.
*ptr: 写入或读取共享内存中的数据.
munmap(): 取消共享内存在当前进程的映射, 为删除共享内存做准备.
shm_unlink(): 删除共享内存.
函数详细说明
1) 函数原型: int shm_open(const char *name, int oflag, mode_t mode);
输入参数: name, 共享内存名; oflag, 打开标志位; mode, 设置共享内存的权限.
返 回 值: int, 成功返回共享内存的文件描述符, 失败返回 - 1;
示 例: fd = shm_open(SHAMNAME,O_CREAT|O_TRUNC|O_RDWR,S_IRUSR|S_IWUSR);
2) 函数原型: int ftruncate(int fd, off_t length);
输入参数: fd, 共享内存的文件描述符; length, 要设置的大小.
返 回 值: int, 成功返回 0, 失败返回 - 1.
示 例: ftruncate(fd, SHMSIZE);
3) 函数原型: void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
输入参数: addr, 要映射到的内存地址, 可以为 NULL;length, 要映射的大小; prot, 对映射存 储区的保护要求; flags, 映射标志位; fd, 要映射的共享内存的文件描述符; offset, 要映射的字节在共享内存中的偏移量.
返 回 值: void*, 无类型指针, 与 malloc() 的返回值类似. 若映射失败返回 MAP_FAILED.
示 例: ptr = mmap(NULL, SHMSIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
4) 函数原型: int munmap(void *addr, size_t length);
输入参数:*addr, 共享内存在进程中映射的地址; length, 映射的字节数.
返 回 值: int, 成功返回 0, 否则返回 1;
示 例: munmap(ptr, SHMSIZE);
5) 函数原型: int shm_unlink(const char *name);
输入参数:*name, 共享内存名;
返 回 值: 成功返回 0, 失败返回 1;
示 例: shm_unlink(SHMNAME);
参数可能取值:
shm_open() | mmap() | ||
oflag | O_RDONLY:共享内存以只读方式打开 | prot | PROT_READ:映射区可读 |
O_RDWR:共享内存以可读写方式打开 | PROT_WRITE:映射区可写 | ||
O_CREAT:共享内存不存在才创建 | PROT_EXEC:映射区可执行 | ||
O_EXCL:如果指定了 O_CREAT,但共享内存已经存在时返回错误 | PROT_NONE:映射区不可访问 | ||
O_TRUNC:如果共享内存已经存在则将其大小设置为 0 | flag | MAP_FIXED:返回值必须等于 addr。因为这不利于移植性,所以不鼓励使用此标志 | |
mode | S_IRWXU:所属用户读、写和执行权限 | MAP_SHARED:多个进程对同一个文件的映射是共享的,一个进程对映射的内存做了修改,另一个进程也会看到这种变化 | |
S_IRUSR :所属用户读权限 | MAP_PRIVATE:多个进程对同一个文件的映射不是共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化 | ||
S_IWUSR:所属用户写权限 | |||
S_I W/R USR/GRP/OTH:mode 的格式 |
示例代码
进程 A 代码:
进程 B 代码:
运行结果, 先后台运行进程 B, 再运行进程 A:
进程 B 用函数 shm_open() 创建了名为 shmtest 的共享内存, 然后调用 ftruncate() 函数对共享内存设置大小, 接着调用 mmap() 函数, 将共享内存映射到进程 B 的地址空间中, while 死循环检查共享内存的值是否为 18.
接着运行进程 A, 用 shm_open() 函数打开进程 B 创建的 shmtest 共享内存, 然后设置大小, 映射到进程 A 的地址空间中, 接着写入 18.
进程 B 接收到进程 A 写入的 18 后, 输出信息到屏幕, 然后终止进程.
来源: http://www.bubuko.com/infodetail-2848610.html