寻找一种无锁的RT安全单读写器单写器结构

moa*_*ala 6 multithreading real-time lock-free

我正在寻找符合这些要求的无锁设计:

  • 一个单一的作家写进结构和单个读取器从该结构中读取(此结构已经存在,并且是安全的,同时读/写)
  • 但在某些时候,结构需要编写器更改,编写器然后初始化,切换和写入新结构(相同类型但具有新内容)
  • 并且在读者读取的下一次,它切换到这个新结构(如果写入器多次切换到新的无锁结构,读取器丢弃这些结构,忽略它们的数据).
  • 必须重用这些结构,即在写入/读取/切换操作期间不允许堆内存分配/释放,以用于RT.

我目前已经实现了一个包含这些结构的多个实例的ringbuffer; 但是这个实现受到以下事实的影响:当编写器使用了环形缓冲区中存在的所有结构时,没有更多的地方可以从结构中改变......但是,其余的环形缓冲区包含一些不必读取的数据由读者但不能被作者重复使用.因此,环形缓冲器不适合这个目的.

无锁设计的任何想法(名称或伪实现)谢谢你考虑过这个问题.

Adr*_*aan 0

你走在正确的轨道上。

线程/进程/处理器之间固定消息的无锁通信 替代文本

如果存在一个生产者和一个消费者,则固定大小的环形缓冲区可用于线程、进程或处理器之间的无锁通信。要执行的一些检查:

head变量仅由生产者写入(写入后作为原子操作)

tail变量仅由消费者写入(作为读取后的原子操作)

陷阱:引入大小变量或缓冲区满/空标志;这些通常是由生产者和消费者共同编写的,因此会给您带来问题。

我通常为此目的使用环形缓冲区。我学到的最重要的教训是,环形缓冲区永远不能包含多个元素。这样,变量和变量分别由生产者和消费者写入。

大/可变大小块的扩展 要在实时环境中使用缓冲区,您可以使用内存池(通常在实时操作系统中以优化形式提供)或将分配与使用分离。我相信后者符合这个问题。

延长队列

如果您需要交换大块,我建议使用带有缓冲区块的池,并使用队列将指针传递给缓冲区。因此,使用带有缓冲区指针的第三个队列。这样,分配可以在应用程序(后台)中完成,并且您的实时部分可以访问可变数量的内存。

应用

while (blockQueue.full != true)
{
    buf = allocate block of memory from heap or buffer pool
    msg = { .... , buf };
    blockQueue.Put(msg)
}

Producer:
   pBuf = blockQueue.Get()
   pQueue.Put()

Consumer
   if (pQueue.Empty == false)
   {
      msg=pQueue.Get()
      // use info in msg, with buf pointer
      // optionally indicate that buf is no longer used
   }
Run Code Online (Sandbox Code Playgroud)