C 用于管理共享MMAP文件的库或工具

C 用于管理共享MMAP文件的库或工具,c,linux,shared-memory,C,Linux,Shared Memory,免责声明:这可能是一个研究问题,因为我找不到我要找的东西,而且它相当具体 问题:我有一个自定义搜索应用程序,需要读取100K到10M之间的文件,每个文件的大小在0.01MB到10.0MB之间。每个文件包含一个数组,可以通过mmap直接作为数组加载。我正在寻找一种解决方案,在需要之前将文件预取到RAM中,如果系统内存已满,则弹出已经处理过的文件 我知道这听起来很像操作系统内存管理和memcached的结合。我实际上寻找的是类似memcached的东西,它不返回键的字符串或值,而是所选数组的起始地址

免责声明:这可能是一个研究问题,因为我找不到我要找的东西,而且它相当具体

问题:我有一个自定义搜索应用程序,需要读取100K到10M之间的文件,每个文件的大小在0.01MB到10.0MB之间。每个文件包含一个数组,可以通过mmap直接作为数组加载。我正在寻找一种解决方案,在需要之前将文件预取到RAM中,如果系统内存已满,则弹出已经处理过的文件

我知道这听起来很像操作系统内存管理和memcached的结合。我实际上寻找的是类似memcached的东西,它不返回键的字符串或值,而是所选数组的起始地址。此外,(这是一个不同的主题)我希望能够管理共享内存,这样CPU核心和RAM之间的距离在NUMA机器上是最短的


我的问题是:“像这样的工具/库是否已经存在?”

您的问题与

我不确定你是否需要找一个图书馆。您只需要了解如何有效地使用系统调用


我相信系统调用可以帮助您。

您的问题与

我不确定你是否需要找一个图书馆。您只需要了解如何有效地使用系统调用


我相信系统调用可以帮助您。

事实上,您有很多文件(可能太多了)。我希望您的文件系统足够好,或者它们位于许多目录中。如果不进行适当的调整,拥有数百万个文件可能会成为一个问题(但我不敢在这方面提供帮助)


我不知道是否是您的应用程序编写和读取了那么多文件。也许你可以考虑切换到一个快速的或类似的,或者也许你可以使用。

< P>确实你有很多文件(也许太多了)。我希望您的文件系统足够好,或者它们位于许多目录中。如果不进行适当的调整,拥有数百万个文件可能会成为一个问题(但我不敢在这方面提供帮助)


我不知道是否是您的应用程序编写和读取了那么多文件。也许你可以考虑切换到一个快速的,或者也许你可以使用。

< P>我曾经为搜索引擎的应用程序做过这件事。它使用了一个LRU链,该链也可以通过文件id和内存地址IIRC进行寻址(通过哈希表)。在每个通道上,热项目都被重新定位到LRU链的头部。内存紧张时(mmap可能会失败…),LRU链的尾部未映射

这个方案的缺点是程序在页面错误时会被阻塞。因为它是单线程的,所以它实际上被阻塞了。将其更改为多线程体系结构需要通过锁和信号量保护哈希和LRU结构

之后,我意识到我在做双缓冲:操作系统本身有一个完美的LRU diskbuffer机制,它可能比我的更智能。只要打开()或mmap()在每个请求上打开每个文件,就只需要一次系统调用,并且(给定最近的活动)与缓冲层的速度一样快,甚至更快


wrt DBMS:使用DBMS是一种干净的设计,但仅为了获取第一个数据块,您就有最少3次系统调用的开销。而且它肯定会(总是)阻塞。但它适合多线程设计,并使您免于锁和缓冲区管理的痛苦

我曾经为一个搜索引擎类应用程序做过这项工作。它使用了一个LRU链,该链也可以通过文件id和内存地址IIRC进行寻址(通过哈希表)。在每个通道上,热项目都被重新定位到LRU链的头部。内存紧张时(mmap可能会失败…),LRU链的尾部未映射

这个方案的缺点是程序在页面错误时会被阻塞。因为它是单线程的,所以它实际上被阻塞了。将其更改为多线程体系结构需要通过锁和信号量保护哈希和LRU结构

之后,我意识到我在做双缓冲:操作系统本身有一个完美的LRU diskbuffer机制,它可能比我的更智能。只要打开()或mmap()在每个请求上打开每个文件,就只需要一次系统调用,并且(给定最近的活动)与缓冲层的速度一样快,甚至更快


wrt DBMS:使用DBMS是一种干净的设计,但仅为了获取第一个数据块,您就有最少3次系统调用的开销。而且它肯定会(总是)阻塞。但它适合多线程设计,并使您免于锁和缓冲区管理的痛苦

你的评论为我指明了正确的方向。这个问题与这里的主要区别是文件数量很多,但每个文件都相对较小。在另一种情况下,情况正好相反。我真正需要做的是不阻塞I/O(至少从使用者的角度来看),并防止内核对使用者尚未读取的文件进行分页。如果有足够的内存,我会将所有数组都保留在内存中。如果您可以预测在接下来的几秒钟内需要哪些文件(或其中的一部分),那么使用
readahead
系统调用(可能在单独的线程中)应该会有所帮助。我有点担心readahead是一个阻塞调用。此外,这个问题的主要动机是展望未来,因为对于一个CPU核心来说,I/O模式似乎很重要,我希望能够扩展到多个核心,而不会让它们挨饿。另一个(单独的问题)是,大多数I/O探查器对于只有一个线程的进程来说是错误的,而对于多线程进程来说则更糟糕。您的评论为我指明了正确的方向。这个问题与这里的主要区别在于文件的数量