将哈希表放入共享内存段的C语言实现

4
希望我的问题有意义: 使用C语言进行编程,我能否在共享内存段中创建哈希表,以便任何具有适当权限的进程可以访问其中的键/值? 如果可以,如何在哈希表创建时指定将其放置在SHM中?是否有建议的哈希表实现允许这样做? 非常感谢。

你是如何处理共享内存的?使用shm_open和mmap吗? - Null Set
还没有开始,但我计划使用shmget、ftok、shmat来完成。 - klayme
3个回答

5

就我所知,没有任何库可以做到这一点。

我知道,如果你编写自己的库或修改现有的库,需要解决的棘手问题是跟踪并修复使用指针的任何代码,并将其替换为使用基础 + 偏移量的代码。

基础是由共享内存创建/打开函数返回的指针,在每个进程中都会不同。偏移量替换了指针。当您需要通过偏移量定位值时,将基础转换为char*,添加偏移量,然后将其转换为your_type*。类似于(bucket_t*)((char*)base + offset)

这是假设您的哈希实现需要指针。如果它们仅使用单值桶和没有值列表,则不需要。

另一个棘手的问题是您需要自己管理内存。而不是调用malloc(),您可以制作自己的函数,可能称之为shm_hash_alloc()。快速启动只需保留指针并在分配内存时将其增加,而不必担心释放它。稍后,您可以使用指针(偏移量)数组来释放各种大小的列表,或者如果您知道对象类型,则为每种类型使用一个列表。在每个空闲块中,您存储下一个空闲块的指针,并且由于其所在的列表,您知道其大小。甚至有更高级的方法,但您可能不需要。


那么,每个附加到共享内存的进程的内存地址或指针都将不同,对吗?这意味着我不能依赖使用指针的内存结构,除非我将它们全部与基地址相关联... 这是一项相当巨大的工作。我想我只需创建一个数组,并扫描其所有成员,直到找到我要找的内容为止。实际上,我只想保留几百或几千个元素。我知道这有多低效。我会考虑一下的。谢谢。 - klayme

3
我在SF上上传了一个用于Linux的共享内存哈希表库(libshmht),以性能为主要特点开发。读/写访问具有相同的响应时间,我认为它可以作为缓存和IPC系统使用。此外,该库还实现了读/写锁,可供多个进程共享。 http://sourceforge.net/projects/libshmht/

1
很棒的库。你把这个库部署到生产环境了吗?(我担心它的稳定性)另外,shmht.cshmht_insert() 函数的 key_size 类型是 unsigned int,但在 shmht.h 中是 size_t,这导致我的编译器报错... - felix021
嗨,felix021。是的,它已经部署到高负载环境中,作为openssl进程间缓存,没有任何问题。感谢编译错误,它是为gcc编译的,可能会在其他编译器上出现一些问题。我会尽快修复它。 - Jon Ander Ortiz Durántez
1
我已经在第11个版本中修复了你在评论中指出的编译错误。 - Jon Ander Ortiz Durántez

1

哈希表只是一种数据结构。只要访问共享内存的模块知道如何构建这个结构,它们就可以访问它。无论你使用哪种实现方式,只要涉及到的所有模块都知道如何读取它即可。

可以将其视为一份报纸。您创建自己的私有内存段 - 这是一个本地报纸。然后您想与周围所有城镇分享它 - 只要人们说同样的语言并且能够阅读它即可。没有特殊的语言用于共享,它只需要是每个人都能理解的语言。

在您的情况下也是如此 - 您可以使用任何哈希表实现,只要所有线程都使用相同的实现即可。


谢谢,我明白你的意思。但问题是,我该如何实例化哈希表,以便在共享内存中创建它?我见过一些哈希表的实现只是返回它被创建的地址,我应该修改它以在给定的地址分配内存吗?再次感谢。 - klayme
@klayme - 是的,如果实现是自己分配内存的话 - 那么你需要修改它以使用你预先分配的内存,或者提供一个你实现的分配器(查看STL模板,了解如何向通用实现提供分配器的示例)。 - littleadv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接