进程间通信:mmap内存映射区

目录

      • 1. mmap—创建内存映射
      • 2. munmap-释放内存映射区
      • 3. 思考问题
      • 4. 案例


1. mmap—创建内存映射

  • 函数原型
void *mmap(
	void *addr,   //映射区首地址,传NULL
	size_t length, //映射区大小(一般指定为文件fd的大小)0
		实际大小是4K的整数倍
	int prot,  //映射区权限 
		PORT_READ----映射区必须有PORT_READ权限
		PORT_WRITE
		PORT_READ | PORT_WRITE
	int flags,  //标志位参数
		MAP_SHARED 修改了内存,数据会同步到磁盘
		MAP_PRIVATE 修改了内存,数据不会同步到磁盘
       int fd,  //文件描述符
       	要映射的文件对应的fd
       off_t offset  //映射文件的偏移量(一般设为0)
       	偏移量必须是4K的整数倍
    ); 
  • 作用:将磁盘文件的数据映射到内存,用户通过[修改内存]就能修改磁盘文件
  • 返回值
    成功:指向映射区首地址的指针
    失败:MAP_FAILED(-1)

2. munmap-释放内存映射区

int munmap(void *addr, size_t len);

  • 参数
    addr:mmap的返回值
    len:mmap的第二个参数

3. 思考问题

  1. 如果对mmap的返回值ptr做++操作,munmap是否能够成功?
    答:不能成功
  2. open文件时,指定的是O_RDONLY,但是创建映射区时,指定的是PROT_READ|PROT_WRITE,能否成功?
    答:不能成功,错误为—>mmap: Permission denied
    规则:open文件指定的权限应该 ≥ mmap第三个参数prot指定的权限
  3. 如果文件的偏移量设置为1000会怎么样?
    答:mmap调用失败,即偏移量必须是4096的整数倍
  4. 什么情况下mmap会调用失败?
    1.第二个参数len=0
    2.第三个参数必须指定PROT_READ
    3.偏移量必须是4096的整数倍
  5. open的时候,用O_CREAT一个新文件后,mmap创建映射区可以成功么?
    答:不能mmap成功,因为O_CREAT新创建文件后,大小为0---->要想mmap成功,需要先对文件进行大小扩展(lseek/truncate)
  6. mmap后关闭文件描述符,对mmap映射有没有影响?
    答:没有影响。
  7. 对ptr越界操作会怎么样?
    答:段错误

4. 案例

int main(){                                                                                                                      
  int fd=open("pipe.c",O_RDWR); //打开文件fd
  if(fd==-1){                                                                                                                    
    perror("open");                                                                                                              
    exit(1);                                                                                                                     
  }                                                                                                                              
  int len=lseek(fd,0,SEEK_END);  //获取文件大小                                                                                                
                                                                                                                                 
  void* ptr=mmap(NULL,len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);//创建映射区
  if(ptr==MAP_FAILED){                                                                                                           
    perror("mmap");                                                                                                              
    exit(1);                                                                                                                     
  }                                                                                                                              
                                                                                                                                 
  printf("%s\n",(char*)ptr); //使用ptr指针访问mmap中的内容
                                                                                                                                 
  int ret=munmap(ptr,len);  //销毁mmap映射区                                                                                                          
  if(ret==-1){
  	perror("munmap fail\n");
  	exit(1);
  }
                                                                                                                                 
  return 0;                                                                                                                      
}    

你可能感兴趣的:(Unix系统编程:,进程间通信IPC)