用于可变长度记录的C ++无锁共享内存

时间:2012-02-02 14:22:07

标签: c++ ipc semaphore shared-memory copy-and-swap

我是IPC的新手。 Writer进程将数据写入共享内存,许多读取器进程读取数据。要写入的数据具有唯一标识符,必须由唯一键索引以便更快地访问(例如STL :: map或hashmap for lookup)。数据也是可变长度记录(XML)(平均长度为200-250字节)。 OS是Intel Xeon四核服务器上的solaris 10(i86pc)。

总数据量超过200G。但是我们将只保留共享内存中的最新数据。历史数据驻留在文件中。共享内存大小约为4G~6G。

没有像Boost :: interprocess

这样的外部库

我有几个问题,可能很多

  1. 效率更高:shared_memory或mmap(内存映射文件)
  2. 如何为可变长度记录构建索引。 [我不知道,可能是一些哈希?]。
  3. 如果将XML转换为固定大小的结构,这将是否整洁(交易 - 结构的大小将是巨大的,近300多个可能的字段)
  4. 我们可以通过提供自定义分配器将任何STL放在shared_memory中吗?
  5. 是否可以在没有信号量的情况下实现(使用CAS的无锁实现)。
  6. 由于

    这个怎么样?

    |--------------------------|
    | start_id   |   end_id    |   ->  range of msg id present in the segment
    |--------------------------|
    | id1 | start_mem | length |   ->
    |--------------------------|   ->
    | id2 | start_mem | length |   -> table of index for the actual data
    |--------------------------|   ->
    | id3 | start_mem | length |   ->
    |--------------------------|   ->
    | id4 | start_mem | length |   ->
    |--------------------------|   ->
    |                          |
    |                          |
    |                          |
    |       data segment       |
    |       varibale length    |
    |       xml are stored     |
    |                          |
    |                          |
    |--------------------------|
    

    当新数据到达且分段已满时。最旧的数据以循环方式被删除。可能有超过1条记录需要删除。

2 个答案:

答案 0 :(得分:0)

最简单的解决方案,如果您需要复杂的索引和其他类似的东西,您应该考虑面向服务的架构而不是共享内存。只需将一个进程指定为主缓存进程,并让它接受来自其他需要数据的进程的本地连接(通过unix域套接字或TCP套接字等)。这使得事情变得更加简单。

如果您不选择此路线,请注意共享内存为 hard 。您要求的是在共享内存中绝对可行 - 您可以在此shmem块等中创建堆分配器等.STL分配器可能工作,但不要指望任何第三方库满意STL分配器使用自定义指针类型。你需要锁(如果你聪明的话,你可能在某些情况下可以避免它们,但不是全部,在这种情况下肯定会吻STL再见),你将不得不重建所有的东西你通常认为理所当然。

同样,我强烈建议您从一个简单的缓存守护进程开始。这在大多数情况下都可以很好地扩展,它只会增加一点延迟。

答案 1 :(得分:-1)

  

是否可以在没有信号量的情况下实现(使用CAS的无锁实现)。

由于无锁(无锁)实现很难设计,我们可能最终陷入混乱,在寻求无锁解决方案之前,您应该考虑以下方面和替代方案:

  • 如果系统中有很多线程,那么调度程序可能会抢占持有锁的线程,因此所有其他线程都将等待锁定(如果不是无锁,则不会给出显着的改进)
  • 如果这可以通过读者 - 写作者锁定来解决。 (作家明显少于读者)。
  • 如果锁定争用的可能性较小,那么您可以考虑使用自旋锁,这将使您与无锁性能相同。