进程间通信——mmap()函数

mmap可以把磁盘文件的一部分直接映射到内存,这样文件中的位置直接就有对应的内存地址,对文件的读写可以直接使用指针来做,而不需要read/write函数。
void *mmap(void *addr,size_t length,int port,int flgs,int fd,off_t offset);
int munmap(void *addr,size_t length);
如果addr参数为NULL,内核会自己在进程地址空间中选择合适的地址建立映射。如果addr不是NULL,则给内核一个提示,应该从什么地方开始映射,内核会选择addr之上的某个合适的地址开始映射。建立映射之后,真正的首地址通过返回值得到。length参数是需要映射的那一部分文件的长度。offset参数是从文件的什么位置开始映射,必须是页大小的整数倍(32位通常是4K)。fd参数表示文件描述符。 port参数的取值有一以下四种:
a、PORT_EXEC:表示映射的这一段可执行;
b、PORT_READ:表示映射的这一段可读;
c、PORT_WRITE:表示映射的这一段可写;
d、PORT_NONE:表示映射的这一段不可访问。
flgs参数的取值有很多种,目前只需要了解两种即可:
MAP_SHARED:多个进程对同一个文件时共享的,一个进程对映射的内存做了修改,另一个进程也会看到这种变化。
MAP_PRIVATE:多个进程对同一个文件的映射是不共享的,一个进程对映射的内存做了修改,另一个进程并不会看到这种变化,也不会真的写到文件中。
mmap如果成功则返回映射的首地址,如果出错则返回常数MAP_FAILED((void *)-1)。当进程终止时,该进程的映射会自动解除,也可以调用munmap解除映射。成功返回0,出错返回-1。
应用举例:和上篇介绍共享内存时的实现功能一样,下面看代码:

读文件

#include <sys/mman.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <error.h>  

int main(int argc, char **argv)  
{  
    int fd;
    char *mapped;  
    /* 打开文件 */  
    if ((fd = open(argv[1], O_RDWR)) < 0) {  
       perror("open");  
    }  

    /* 将文件映射至进程的地址空间 */  
    if ((mapped = (char *)mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED {  
        perror("mmap");
    }  
  /* 文件已在内存, 关闭文件也可以操纵内存 */  
    close(fd);  

  /* 每隔两秒查看存储映射区是否被修改 */    
     while (1) {  
        printf("%s\n", mapped);  
        sleep(2);  
   }  
    return 0;  
}  

写文件

#include <stdio.h>
#include <error.h>
#include <sys/mman.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <unistd.h>  
#include <error.h> 


int main(int argc, char **argv)  
{  
        int fd, i =  0; 
         char *mapped;           
         /* 打开文件 */  
          if ((fd = open(argv[1], O_RDWR,0644)) < 0) {  
                 perror("open");  
            }  

         /* 共享文件映射将无法修改文件 */  
         if ((mapped = (char *)mmap(NULL,1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {  
             perror("mmap");  
          }  

         /* 映射完后, 关闭文件也可以操纵内存 */  
        close(fd);  

         /* 修改一个字符 */
        while(1){
            mapped[i++] = '#';  
            mapped[i] = '\0';
            sleep(1);
        }    
        return 0;  
}                   
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值