可以无限期地访问文件映射的内存

时间:2016-05-29 21:55:09

标签: unix x86 x86-64 freebsd

是否有可能无限期地延长对内存位置的读取(并且对于另一个线程允许在任意超时后完成读取)?

例如,使用阻塞套接字,我们可以在使用read系统调用时停止进程:

fd = socket(AF_UNIX, SOCK_DGRAM, 0);
read(fd, buffer, 256);

通常我们不能mmap套接字,但我基本上喜欢直接访问内存时会发生同样的事情:

int x = *(int *)map;

我知道让内存访问花费更长时间的技术,例如在访问内存之前使用madvise来分页内存,但我正在寻找一种让它无限期使用的方法。

我考虑在文件上使用mmap,然后“锁定”该文件,但找不到合适的接口。 flock系统调用似乎没有这种方式。

具体来说,我对FreeBSD for x86-64架构很感兴趣,但对其他类Unix系统(如Linux和其他架构)的答案也不胜感激。

1 个答案:

答案 0 :(得分:3)

您可以使用mprotect(..., PROT_NONE)将包含map的网页标记为无法访问。当您尝试访问它时,会发生页面错误并引发SIGSEGV

您可以为SIGSEGV安装一个处理程序,使用额外的siginfo_t参数声明。查看此结构的si_addr成员以检查错误地址是否与map匹配;这使您可以区分对此地址的访问与代码中实际错误的其他错误(例如,NULL取消引用)。如果是,那么信号处理程序可以等到被告知继续由另一个线程继续。准备好后,使用mprotect(或适当的PROT_READ)呼叫PROT_WRITE并从信号处理程序返回;故障指令重新启动并继续执行。

这是一个相当丑陋的黑客,我建议你好好看看为什么你认为你需要这样做。您的问题似乎可能是XY problem