boost::interprocess 內存映射文件的用法

一、閒聊

  今天項目中要讀寫一個將近40M的文件,發現使用fstream讀文件時,預先分配一個40M的緩衝區buffer時,隨機性的會申請內存失敗,因此查了下相關資料,發現使用內存映射文件可以解決此類讀寫大文件的問題。內存文件映射其實是內存中分配了一塊區域映射到文件所在的物理磁盤上,內存和物理磁盤的數據交換是以頁大小處理的,因此在操作過程中,不會將整個文件緩存到內存上,因此使用的內存特別的小,但對於程序員來說,映射的指針就如操作一塊普通的內存一樣方便,所有的頁交換都由操作系統來處理了。

二、代碼測試

boost::interprocess提供的文件映射類特別的簡單,主要是file_mapping和mapped_region,具體的構造參數說明,可以去官網查看,這裏只是提供一個例子。

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
using namespace boost::interprocess;
void main()
{
	file_mapping m_file("test.txt", read_write);
	mapped_region region(m_file, read_write);

	void * addr       = region.get_address();
	std::size_t size  = region.get_size();
}

file_mapping類

第一個參數是文件名,該文件必須存在,不然會拋出“找不到系統文件”的異常,它是不會幫你自動生成文件的。

第二個參數是打開模式,目前只有read_only和read_write兩種模式,一個是隻讀,一個是讀寫都可以。

mapped_region類

第一個參數是file_mapping的對象。

第二個參數是打開模式,最好file_mapping的打開模式一致。

get_address()就是取得文件的首地址了。

get_size()是取得文件的長度。


程序裏爲了保證文件操作的原子性,因此需要加鎖,而boost也提供了這種文件鎖的機制file_lock,其實它就是拿一個文件來當互斥量,那我們的代碼就變成了這樣。

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
using namespace boost::interprocess;
void main()
{
	file_lock f_lock("test.txt");
	sharable_lock<file_lock> sh_lock(f_lock);
	file_mapping m_file("test.txt", read_write);
	mapped_region region(m_file, read_write);

	void * addr       = region.get_address();
	std::size_t size  = region.get_size();
}

file_lock需要一個文件名的參數,如果該文件不存在也會拋異常,映射文件和鎖文件可以是同一個。

sharable_lock是共享鎖,也可以使用獨佔鎖scoped_lock,共享鎖和獨佔鎖的區別這裏不細講,可以問度娘。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章