情况就是这样。
大数据缓冲区(超出合理的RAM) 消费)是由该计划产生的。
该程序同时提供一个允许网络的websocket 客户端指定要查看的此数据缓冲区的一小部分。
为了支持第一个目标,使用标准方法编写文件(我使用便携式C-stdio fopen
和fwrite
,因为它显示比各种&#更快? 34;纯C ++"方法。没关系。数据被附加到文件; stdio将缓冲写入并定期刷新它们。)
为了支持第二个目标(在BSD上,特别是在iOS上),文件被打开(open
来自sys/fcntl.h
- 而不是,因为stdio.h
是可移植的})和内存映射(mmap
来自sys/mman.h
- 同上)。通过决定使用内存映射,我必须放弃使用此代码的一些可移植性。似乎Boost是我可以看到的,以避免车轮重新发明。
无论如何,我的问题是关于我应该如何做到这一点,因为至少会有两个线程:定期附加到文件的主程序线程,以及网络(或工作者)线程响应Web请求并提供从映射到磁盘上文件的内存区域读取的数据。
假设文件大小为1024字节,则mmap
最初调用1024字节。当主线程将另外512个字节写入文件时,如何通知网络线程或了解有关文件当前实际大小的任何信息(以便它可以再次使用munmap
和mmap
对应新尺寸的较大缓冲区)?此外,如果我天真地这样做,我很担心主线程报告写入512字节的情况,因此另一个线程现在映射文件的1536个字节,但并不是所有新的512字节实际写入磁盘然而(操作系统仍在努力编写它,也许)。现在发生了什么?可能会出现一些垃圾吗?我的程序会崩溃吗?
如何确定何时正确刷新数据?刷新数据后如何及时通知我,以便我可以对内存进行映射?
特别是,调用fflush
是保证文件现在更新为w.r.t的唯一方法。流,然后我可以保证(一旦fflush
返回)内存映射可以访问新大小而没有访问冲突?那么fsync
呢?
答案 0 :(得分:0)
当您以mmap
的形式直接使用POSIX API时,您也应该直接使用它来写作。 POSIX和LibC界面不能很好地协同发挥。
write
是一个系统调用,它将数据直接传输到内核。逐字节写入会很慢,但是对于写入大缓冲区来说,它的速度要快一点,因为它的开销较小(fwrite
最终会在引擎盖下调用write
。而且fwrite
+ fflush
效率肯定更高,因为那些可能最终会被调用write
两次或更多次,如果您直接调用write
,那么它只是一个
mmap的文档不是很清楚,但似乎你不能请求比实际文件更多的字节。