简体   繁体   English

不清楚为什么mmap没有按照我的想法去做。 C ++ Linux

[英]Not very clear why mmap is not doing what I think it should. C++ Linux

I trying to make a log file class, the process I want to follow is: 我试图制作一个日志文件类,我要遵循的过程是:

  • Open the file (Or create it) 打开文件(或创建文件)
  • Map the file on memory 将文件映射到内存
  • Close de file 关闭文件
  • Write to memory 写入内存

The file will have a size of 1024KB (SIZE_KB constant). 该文件的大小为1024KB(常量为SIZE_KB)。

So far this is what I'm doing: 到目前为止,这是我正在做的事情:

Im creating the file with read and write permissions for the owner (S_IRUSR | S_IWUSR) and read permissions for the rest (S_IRGRP | S_IROTH). 我创建的文件具有所有者的读取和写入权限(S_IRUSR | S_IWUSR),其余具有读取权限(S_IRGRP | S_IROTH)。

// Open the file. If the file doesnt exists it will create it
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int fd = open(path.c_str(), O_CREAT | O_RDWR, mode);

After that, I check if fd is -1 : 之后,我检查fd是否为-1

if (fd < 0)
    throw std::system_error(errno, std::system_category(), "couldnt open history");

#ifdef _DEBUG_
    std::clog << "History with file descriptor " << fd << " opened" << std::endl;
#endif

Now, I map the file, but first I need to set a variable length with the size of the file which must be a mutiple of sysconf(_SC_PAGE_SIZE) : 现在,我映射了文件,但是首先我需要设置一个可变长度的文件,该文件的大小必须是sysconf(_SC_PAGE_SIZE)

size_t length = (int)ceil(SIZE_KB*1024.0/sysconf(_SC_PAGE_SIZE))*sysconf(_SC_PAGE_SIZE);  
/* ceil( size / page_size)*page_size*/

#ifdef _DEBUG_
    std::clog << "Length is " << length << " bytes" << std::endl;
#endif

Mapping, block_start is a private char pointer: 映射, block_start是私有char指针:

block_start = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  • Extra question: M_SHARED option make this part of the memory accesible to other processes (?). 额外的问题:M_SHARED选项使此部分内存可用于其他进程(?)。 Why is it also used to make the SO save the changes made in the virtual memory to the actual file ?. 为什么还使SO将虚拟内存中所做的更改保存到实际文件中?

Check for errors: 检查错误:

#ifdef _DEBUG_  
    std::clog << Returned: " << (int*)block_start << std::endl;
#endif

if (block_start == MAP_FAILED)
    throw std::system_error(errno, std::system_category(), "couldnt map memory");

#ifdef _DEBUG_
    std::clog << "History memory mapped" << std::endl;
#endif

And close the file: 并关闭文件:

int result = close(fd);
if (result < 0)
    throw std::system_error(errno, std::system_category(), "error closing history");

#ifdef _DEBUG_
    std::clog << "History with file descriptor " << fd << " closed" << std::endl;
#endif

Now, I should be able to add information to mapped memory, so I tried doing: 现在,我应该能够向映射的内存中添加信息,因此我尝试这样做:

std::cout << "Attemping to write on first" << std::endl;
*block_start = 'A';
std::cout << "End" << std::endl;

(Inside the constructor) (在构造函数内部)

This is the output I have: 这是我的输出:

History with file descriptor 3 opened
Length is 1048576 bytes
Returned: 0x7f7e9160a000
History memory mapped
History with file descriptor 3 closed
Attemping to write on first
Bus error (core dumped)

I think it probably have to do with the file size, since the created file have 0 size, but Im telling mmap to map a size of SIZE_KB*1024 bytes, so why is this not working ? 我认为这可能与文件大小有关,因为创建的文件的大小为0,但是我告诉mmap映射SIZE_KB*1024字节的大小,所以为什么这不起作用?

-rw-r--r-- 1 dark dark 0 Dec 13 16:15 /home/dark/talk.log

Because mmap will not map beyond the size of the file. 因为mmap不会映射超出文件的大小。 If you're mmaping an empty file, your effective mmap size is 0. 如果要映射一个空文件,则有效的mmap大小为0。

You need to set the size of the file, via truncate() or ftruncate(), before mmaping it, and the size of the file, and the mmapped size, must agree. 映射之前,您需要通过truncate()或ftruncate()设置文件的大小,并且文件的大小和映射的大小必须一致。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM