LINUX学习笔记
mmap 进程通信
1. mmap 函数声明及头文件包含
man 2 mmap
#include<sys/mman.h>
/* 创建映射区 */
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
/* 释放映射区 */
int munmap(void *addr, size_t length);
1.1 参数说明
参数:
- addr:指定映射区的首地址。通常传NULL,表示让系统自动分配
- length:共享映射区的大小(<= 文件实际大小)
- prot:共享内存区的读写属性
PROT_READ
PROT_WRITE
PROT_READ | PROT_WRITE- flag:标注共享内存的共享属性
MAP_SHARED(对内存的修改会反映到磁盘上)
MAP_PRIVATE(对内存的修改不会反映到磁盘上)- fd:用于创建共享内存映射区的那个文件的 文件描述符
- offset:从文件偏移位置开始建立映射区 (必须是4k的整数倍4096)默认0,表示映射文件全部
mmap返回值:
- 成功—映射区的首地址
- 失败—MAP_FAILED( 实质(void*)-1 ),设置errno
!!!!!mmap 极易容易出错,切记一定要检查mmap的返回值!!!!!!
munmap返回值:
- 成功— 0
- 失败— -1,设置errno
1.2 mmap 通信demo
- open 创建一个文件,并用 lseek 或者 ftruncate 拓展文件大小
- mmap创建映射区
- 往映射区写
- 读映射区
- 释放映射区
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<pthread.h>
#include<sys/mman.h>
#include<fcntl.h>
void sys_error(const char * str)
{
perror(str);
exit(1);
}
int main(int argc, char * argv [])
{
int fd, ret;
char* p = NULL;
fd = open("testmap", O_RDWR | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
{
sys_error("open error\n");
}
/*
lseek(fd, 10 , SEEK_END); // 与 ftruncate 等效
write(fd, "\0", 1);
*/
ftruncate(fd, 10); // 需要写权限才能拓展文件大小
int len = lseek(fd, 0, SEEK_END);
p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) // 返回值一定要检查
{
sys_error("mmap error\n");
}
strcpy(p, "he