使用mmap读取时同时写入文件

时间:2014-03-27 05:26:12

标签: c++ multithreading file-io mmap

情况就是这样。

  1. 大数据缓冲区(超出合理的RAM) 消费)是由该计划产生的。

  2. 该程序同时提供一个允许网络的websocket 客户端指定要查看的此数据缓冲区的一小部分。

  3. 为了支持第一个目标,使用标准方法编写文件(我使用便携式C-stdio fopenfwrite,因为它显示比各种&#更快? 34;纯C ++"方法。没关系。数据被附加到文件; stdio将缓冲写入并定期刷新它们。)

    为了支持第二个目标(在BSD上,特别是在iOS上),文件被打开(open来自sys/fcntl.h - 而不是,因为stdio.h是可移植的})和内存映射(mmap来自sys/mman.h - 同上)。通过决定使用内存映射,我必须放弃使用此代码的一些可移植性。似乎Boost是我可以看到的,以避免车轮重新发明。

    无论如何,我的问题是关于我应该如何做到这一点,因为至少会有两个线程:定期附加到文件的主程序线程,以及网络(或工作者)线程响应Web请求并提供从映射到磁盘上文件的内存区域读取的数据。

    假设文件大小为1024字节,则mmap最初调用1024字节。当主线程将另外512个字节写入文件时,如何通知网络线程或了解有关文件当前实际大小的任何信息(以便它可以再次使用munmapmmap对应新尺寸的较大缓冲区)?此外,如果我天真地这样做,我很担心主线程报告写入512字节的情况,因此另一个线程现在映射文件的1536个字节,但并不是所有新的512字节实际写入磁盘然而(操作系统仍在努力编写它,也许)。现在发生了什么?可能会出现一些垃圾吗?我的程序会崩溃吗?

    如何确定何时正确刷新数据?刷新数据后如何及时通知我,以便我可以对内存进行映射?

    特别是,调用fflush是保证文件现在更新为w.r.t的唯一方法。流,然后我可以保证(一旦fflush返回)内存映射可以访问新大小而没有访问冲突?那么fsync呢?

1 个答案:

答案 0 :(得分:0)

当您以mmap的形式直接使用POSIX API时,您也应该直接使用它来写作。 POSIX和LibC界面不能很好地协同发挥。

write是一个系统调用,它将数据直接传输到内核。逐字节写入会很慢,但是对于写入大缓冲区来说,它的速度要快一点,因为它的开销较小(fwrite最终会在引擎盖下调用write。而且fwrite + fflush效率肯定更高,因为那些可能最终会被调用write两次或更多次,如果您直接调用write,那么它只是一个

mmap的文档不是很清楚,但似乎你不能请求比实际文件更多的字节。