【问题标题】:lock free arena allocator implementation - correct?无锁竞技场分配器实现 - 正确吗?
【发布时间】:2009-08-28 20:57:56
【问题描述】:

对于一个简单的指针增量分配器(它们有正式名称吗?)我正在寻找一种无锁算法。这似乎微不足道,但我想得到一些反馈我的实施是否正确。

不是线程安全的实现:

byte * head;  // current head of remaining buffer
byte * end;   // end of remaining buffer

void * Alloc(size_t size)
{
   if (end-head < size)
     return 0; // allocation failure

   void * result = head;
   head += size;
   return head;
}

我对线程安全实现的尝试:

void * Alloc(size_t size)
{
  byte * current;
  do 
  {
     current = head;
     if (end - current < size)
        return 0;  // allocation failure
  } while (CMPXCHG(&head, current+size, current) != current));
  return current;
}

其中CMPXCHG 是与(destination, exchangeValue, comparand) 参数的互锁比较交换,返回原始值

对我来说看起来不错 - 如果另一个线程在 get-current 和 cmpxchg 之间分配,则循环再次尝试。有cmets吗?

【问题讨论】:

  • @Neil - 我以前见过这样的模式。从这样的竞技场中为操作的不同部分快速分配内存,并在完成后释放整个事物。
  • 正如迈克尔所说 - 你只释放整个块(头)。非常适合构建大型、不可变/仅增长的数据结构。
  • 这称为线性分配器。
  • @kotlinksi:从来没有听说过这个词,但它至少是明确的。

标签: c++ multithreading lock-free allocator


【解决方案1】:

您当前的代码似乎可以正常工作。您的代码的行为与以下代码相同,这是一个简单的模式,您可以使用它来实现任何对单个数据字进行操作且无副作用的无锁算法

do
{
    original = *data; // Capture.

    result = DoOperation(original); // Attempt operation
} while (CMPXCHG(data, result, original) != original);

编辑:我最初的联锁添加建议在这里不太适用,因为如果没有足够的空间,您支持尝试分配和失败。如果您使用 InterlockedAdd,您已经修改了指针并导致后续分配失败。

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多