C++ 使内存页无效

C++ 使内存页无效,c++,linux,C++,Linux,我正在实现一个巨大的压缩光栅文件阅读器。部分解压是动态执行的。仅对光栅的请求区域进行解压缩并存储在内存缓存中。读卡器的工作原理与文件的内存映射类似,但数据并没有映射到内存1:1,而是解压缩 它是使用匿名内存映射实现的: char* raster_cache = static_cast<char*>(mmap(0, UNCOMPRESSED_RASTER_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); char*raste

我正在实现一个巨大的压缩光栅文件阅读器。部分解压是动态执行的。仅对光栅的请求区域进行解压缩并存储在内存缓存中。读卡器的工作原理与文件的内存映射类似,但数据并没有映射到内存1:1,而是解压缩

它是使用匿名内存映射实现的:

char* raster_cache = static_cast<char*>(mmap(0, UNCOMPRESSED_RASTER_SIZE, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
char*raster\u cache=static\u cast(mmap(0,未压缩的光栅大小,无保护,映射私有,映射匿名,-1,0));
读取尚未缓存的区域会发出分段冲突信号,该信号使用libsigsegv捕获和处理(请参阅):

struct CacheHandlerData
{
std::互斥互斥;
//解压缩所需的其他数据
};
int cache\u sigsegv\u处理程序(无效*错误\u地址,无效*用户\u数据)
{
void*page_address=reinterpret_cast(reinterpret_cast(fault_address)&~(page_SIZE-1));
CacheHandlerData*数据=静态转换(用户数据);
std::lock\u guard lock(数据->互斥);
缓存的无符号字符=0;
mincore(页面地址,1,&缓存);
如果(!缓存)
{
保护(页面地址、页面大小、保护写入);
//解压缩整个页面
保护(页面地址、页面大小、保护读取);
}
返回1;
}
问题是缓存的页面永远留在内存中。因为我在页面上写东西,所以它们被标记为脏的,并且从不失效

问题:是否有可能将页面标记为不脏

在系统内存不足的情况下,页面将像普通磁盘缓存一样从内存中删除。还需要为删除的页面调用mprotect(page_address、page_SIZE、PROT_NONE),以便在再次访问页面时导致分段冲突

多谢各位


编辑:我可以使用临时文件备份映射,而不是匿名映射。如果系统内存不足,页面将交换到磁盘。但是这个解决方案失去了使用压缩数据的好处(更小的磁盘大小,可能更快的读取)。

您可以尝试fuse,我想它有mmap挂钩。顺便说一句,信号处理函数中有“安全调用”列表,请参阅信号(7)。我认为信号处理程序中的许多函数调用起来不安全。
struct CacheHandlerData
{
    std::mutex mutex;

    // other data needed for decompression
};

int cache_sigsegv_handler(void* fault_address, void* user_data)
{
    void* page_address = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(fault_address) & ~(PAGE_SIZE - 1));

    CacheHandlerData* data = static_cast<CacheHandlerData*>(user_data);
    std::lock_guard<std::mutex> lock(data->mutex);

    unsigned char cached = 0;
    mincore(page_address, 1, &cached);
    if (!cached)
    {
        mprotect(page_address, PAGE_SIZE, PROT_WRITE);

        // decompress whole page

        mprotect(page_address, PAGE_SIZE, PROT_READ);
    }

    return 1;
}