2015-12-13 16 views
1

我試圖讓一個日誌文件類,這個過程中我想遵循的是:不太清楚爲什麼mmap沒有做我認爲應該做的事。 C++的Linux

  • 打開文件(或創建)
  • 地圖文件上的內存
  • 關閉德文件
  • 寫入內存

該文件的大小爲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選項使內存入店到其他進程的這部分(?)。爲什麼它也用於使SO將虛擬內存中所做的更改保存到實際文件中?

檢查錯誤:

#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

因爲mmap不會映射超出文件的大小。如果您要映射一個空文件,那麼您的有效mmap大小爲0.

您需要在對文件進行壓縮之前通過truncate()或ftruncate()設置文件的大小以及文件的大小,和mmap大小,必須同意。

+0

最後一句話有點不對。你可以''繪製比文件大小更小的段。 –

+0

謝謝,解決了這個問題,我認爲這沒有必要。任何對M_SHARED問題的回答? – Ediolot

+0

因爲它是一回事。因爲其他進程共享相同內存段的唯一方法是讓它們映射相同的文件。因此,您必須讓MAP_SHARED標誌也更新底層文件的內容。否則,其他進程將不會看到您的進程對mmapped文件所做的更改。 –

相關問題