结合CSAPP两个习题说明mmap使用方法

1 篇文章 0 订阅

【man mmap】中可以看到该函数的定义。

习题9.14:从文件中读取,然后写入。

#include <iostream>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

using namespace std;   

int main(int argc, char* argv[])
{

    int fd = open(argv[1], O_RDWR);

    // struct stat f_stat; 
    // f_stat(fd, &f_stat);
    
    int len = lseek(fd, 0, SEEK_END);

    printf("fd = %d, len %d\n", fd, len);
    // char * arr = static_cast<char*>(mmap(NULL, len, PROT_READ | PROT_WRITE,
    //                                     MAP_PRIVATE, fd, 0));

        char * arr = static_cast<char*>(mmap(NULL, len, PROT_READ | PROT_WRITE,
                                        MAP_SHARED, fd, 0));

    // 1、访问中,需要注意参数设置问题,遇到了两次错误,分别提示13、22
        //  设置为 MAP_SHARED 需要注意权限问题   

    // 2、mmap执行失败,返回值为MAP_FAILED(-1),而不是通常的NULL
    if(arr == MAP_FAILED)
    {
        printf("errno:%d\n", errno);
        return 0;
    }
    
    // 为什么这里关闭了fd还是能写入?
    // 因为用了MAP_SHARED模式,所以打开与否没关系了,见下面的测试情况
    close(fd);    
    printf("before context is : %s\n", arr);
    write(1, arr, len); //通过标准输出(stdout,为1)输出

    *arr = 'J';
    printf("after context is : %s\n", arr);
    int ret = write(fd, arr, len); //stdout输出

    // write(-1) char to file, errno(9)
    // 9 EBADF Bad file descriptor.  A file descriptor argument was out of
            //  range, referred to no open file, or a read (write) request was
            //  made to a file that was only open for writing (reading).
    printf("write(%d) char to file, errno(%d)\n", ret, errno);

    munmap(arr, len);

    return 0;
}

这里有几点需要注意:

  • 1、访问中,需要注意参数设置问题,遇到了两次错误,分别提示13、22
    • 设置为 MAP_SHARED 需要注意权限问题
  • 2、mmap执行失败,返回值为MAP_FAILED(-1),而不是通常的NULL

上面的疑问:
为什么close(fd)后还能写成功,其实通过后面的测试实验可以看出,其实这里已经关闭成功,write时并未成功,而是在mmap 中成功了。具体到mmap中,MAP_SHAREDMAP_PRIVATE的区别如下:

MAP_SHARED
      Share this mapping.  Updates to the mapping are visible to
      other processes mapping the same region, and (in the case
      of file-backed mappings) are carried through to the
      underlying file.  (To precisely control when updates are
      carried through to the underlying file requires the use of
      msync(2).)

MAP_PRIVATE
      Create a private copy-on-write mapping.  Updates to the
      mapping are not visible to other processes mapping the
      same file, and are not carried through to the underlying
      file.  It is unspecified whether changes made to the file
      after the mmap() call are visible in the mapped region.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值