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
最後一句話有點不對。你可以''繪製比文件大小更小的段。 –
謝謝,解決了這個問題,我認爲這沒有必要。任何對M_SHARED問題的回答? – Ediolot
因爲它是一回事。因爲其他進程共享相同內存段的唯一方法是讓它們映射相同的文件。因此,您必須讓MAP_SHARED標誌也更新底層文件的內容。否則,其他進程將不會看到您的進程對mmapped文件所做的更改。 –