如何在Linux中为内存映射文件提供扩展写入功能?
我正在努力将一些代码从AIX移植到
Linux.部分代码使用
shmat() system call创建新文件.当在可写模式下与SHM_MAP一起使用时,可以将文件扩展到其原始长度之外(在我的情况下为零):
(AIX中的“段”是256 MB的地址空间块,“页面”通常是4 KB.) 我想在Linux上做的是以下内容: >保留一大块地址空间(它不必大到256 MB,这些不是很大的文件) 我知道我可以在Windows上使用VirtualProtect函数,PAGE_GUARD内存保护位和structured exception handler执行此操作.在Linux上执行相同操作的相应方法是什么?是否有更好的方法在Linux上实现这种写入扩展功能? 我已经考虑过: >使用具有一些固定大小的mmap(),但我无法分辨应用程序代码写入了多少文件 当然,我只想对应用程序代码进行最小的更改即可. 解决方法
这与我曾经做过的家庭作业非常相似.基本上我有一个“页面”列表和一个“框架”列表,以及相关信息.使用SIGSEGV我会捕获故障并根据需要更改内存保护位.我将包含您可能觉得有用的部分.
创建映射.最初它没有权限. int w_create_mapping(size_t size,void **addr) { *addr = mmap(NULL,size * w_get_page_size(),PROT_NONE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0 ); if (*addr == MAP_FAILED) { perror("mmap"); return FALSE; } return TRUE; } 安装信号处理程序 int w_set_exception_handler(w_exception_handler_t handler) { static struct sigaction sa; sa.sa_sigaction = handler; sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask,SIGSEGV); sa.sa_flags = SA_SIGINFO; if (sigaction(SIGSEGV,&sa,&previous_action) < 0) return FALSE; return TRUE; } 异常处理程序 static void fault_handler(int signum,siginfo_t *info,void *context) { void *address; /* the address that faulted */ /* Memory location which caused fault */ address = info->si_addr; if (FALSE == page_fault(address)) { _exit(1); } } 增加保护 int w_protect_mapping(void *addr,size_t num_pages,w_prot_t protection) { int prot; switch (protection) { case PROTECTION_NONE: prot = PROT_NONE; break; case PROTECTION_READ: prot = PROT_READ; break; case PROTECTION_WRITE: prot = PROT_READ | PROT_WRITE; break; } if (mprotect(addr,num_pages * w_get_page_size(),prot) < 0) return FALSE; return TRUE; } 由于团队可能会再次使用相同的作业,因此我无法公开全部使用. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |