Unix C 学习之内存映射

  1. mmap(2)
     
    #include <sys/mman.h>
    void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
    功能:将文件和设备映射到内存
    参数:
    addr 指示内核分配的地址,linux会分配附近的页,该参数一般为NULL,由内核选择地址建立映射区域
    length 指定了映射区域的长度
    prot
    PROT_EXEC Pages may be executed.
    PROT_READ Pages may be read.
    PROT_WRITE Pages may be written.
    PROT_NONE Pages may not be accessed.
     
    flags
    二选一:
    MAP_SHARED 共享映射区域 对映射区域的更新可以被另外一个映射同一文件的进程看到,并且同步到底层的文件中
     
    MAP_PRIVATE 私有映射 对映射区域的更新不可以被另外一个映射同一文件的进程看到,并且不同步到底层的文件中
     
    另外 以下的标记可以选择0或多个按位或到flags中,详见man手册
    MAP_ANONYMOUS 匿名映射 fd被忽略fd设置为-1 offset被忽略.
     
    fd 指定了文件 将这个文件映射到进程的虚拟地址空间里
    offset 指定了文件映射的起始位置 这个值必须是页的整数倍
    返回值:
    错误 MAP_FAILED被返回 errno被设置
    成功 返回映射区域的起始地址

  2. int munmap(void *addr, size_t length);
    功能 解除文件或设备到内存的映射
    参数
    addr 指定了映射区域的起始地址
    length 指定了长度
    返回值 成功 0 错误 -1 errno被设置

匿名映射
物理地址空间 有些设备文件没有文件名.这些设备的确是一个文件但是没有记录到文件管理系统中
这类文件称为匿名文件.个人理解:匿名映射就是建立一个虚拟地址到内存中物理地址的一个映射关系,然后对虚拟内存的操作,会折射到实际的物理内存中,与非匿名映射相比,只是匿名映射时,与文件无关,匿名映射更像是标准C语言中的malloc,calloc等

#ifndef     __T_STDIO_H__
#define     __T_STDIO_H__

#include <stdio.h>
#define E_MSG(STR,VAL)  do{\
                            perror(STR);\
                            return (VAL);\
                        }while(0)
#endif

 
匿名映射

#include <t_stdio.h>
#include <sys/mman.h>
#include <string.h>

int main(void){
    int prot = PROT_READ | PROT_WRITE;
    int flags = MAP_PRIVATE | MAP_ANONYMOUS;
    //建立匿名映射,物理地址空间映射到进程的虚拟地址
    char *p = (char *)mmap(NULL, 1024, prot, flags, -1, 0); 
    if(p==MAP_FAILED) E_MSG("mmap", -1);
    //使用p
    strcpy(p, "hello beijing");
    printf("%s\n", p); 
    //解除映射关系
    munmap(p,1024);
    return 0;
}

 
文件映射

#include <t_stdio.h>
#include <sys/mman.h>
#include <t_file.h>

int main(int argc, char *argv[]){
    int prot = PROT_READ | PROT_WRITE;
    int flags = MAP_SHARED;
    //以可读可写的方式打开文件
    int fd = open(argv[1], O_RDWR);
    if(fd == -1) E_MSG("open", -1);
    //将文件映射到进程的虚拟地址空间
    int *p = (int *)mmap(NULL, 6, prot, flags, fd, 0); 
    if(p==MAP_FAILED){
    	//关闭文件描述符,不解除映射
    	close(fd);
	    E_MSG("mmap", -1);
    }
    //到这里已经建立起映射了
	//关闭文件描述符,不解除映射
    close(fd);
    *p = 0x31323334;
    //解除映射
    munmap(p,6);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值