不清楚为什么mmap没有做我认为应该做的事情。 C ++ Linux

时间:2015-12-13 17:28:31

标签: c++ linux mmap coredump

我尝试创建一个日志文件类,我想要遵循的过程是:

  • 打开文件(或创建它)
  • 将文件映射到内存
  • 关闭文件
  • 写入内存

该文件的大小为1024KB(SIZE_KB常量)。

到目前为止,这就是我正在做的事情:

我创建的文件具有对所有者的读写权限(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);

之后,我会检查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

现在,我映射文件,但首先我需要设置一个变量长度,文件大小必须是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

映射,block_start是一个私有字符指针:

block_start = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  • 额外的问题:M_SHARED选项使这部分内存可以访问其他进程(?)。为什么它还用于将虚拟内存中的更改保存到实际文件中?。

检查错误:

#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

关闭文件:

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

现在,我应该能够向映射内存添加信息,所以我尝试了:

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

(在构造函数内)

这是我的输出:

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)

我认为它可能与文件大小有关,因为创建的文件大小为0,但我告诉mmap映射SIZE_KB*1024字节的大小,为什么这不起作用?

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

1 个答案:

答案 0 :(得分:1)

因为mmap的映射不会超出文件的大小。如果您正在对空文件进行mmaping,则有效的mmap大小为0。

你需要通过truncate()或ftruncate()来设置文件的大小,然后才能进行mmaping,文件大小和mmapped大小必须一致。