从【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_SHARED
和 MAP_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.