我有困难理解任何数据结构如何可以是“非阻塞”的。
假设你正在创建一个“非阻塞”哈希表。在某个时刻,你的哈希表变得太满了,所以你必须重新哈希到一个更大的表中。
这意味着你需要分配内存,这是一种全局资源。因此,似乎你必须获取某种锁来防止堆的全局破坏...无论你的数据结构本身可能存在的问题如何!
但是这意味着每个其他线程都必须在你分配内存时被阻塞...
我错过了什么?
(如何)可以在不阻塞正在执行相同操作的另一个线程的情况下分配内存吗?
我有困难理解任何数据结构如何可以是“非阻塞”的。
假设你正在创建一个“非阻塞”哈希表。在某个时刻,你的哈希表变得太满了,所以你必须重新哈希到一个更大的表中。
这意味着你需要分配内存,这是一种全局资源。因此,似乎你必须获取某种锁来防止堆的全局破坏...无论你的数据结构本身可能存在的问题如何!
但是这意味着每个其他线程都必须在你分配内存时被阻塞...
我错过了什么?
(如何)可以在不阻塞正在执行相同操作的另一个线程的情况下分配内存吗?
Push(T item)
{
Node node = new Node(); // allocate node memory
Node initial;
do
{
initial = head;
node.Value = item;
node.Next = initial;
}
while (CompareAndSwap(head, node, initial) != initial);
}
Pop()
{
Node node;
Node initial;
do
{
initial = head;
node = initial.Next;
}
while (CompareAndSwap(head, node, initial) != initial);
T value = initial.Value;
delete initial; // deallocate node memory
return value;
}
CompareAndSwap
是一种非阻塞原子操作,它将内存地址中的值替换为新值并返回旧值。如果旧值与期望值不匹配,则需要循环尝试直到成功为止。非阻塞的意思只是你永远不会无限期地等待,而不是根本不等待。只要你的堆也使用非阻塞算法实现,你就可以在其上实现其他非阻塞算法。
epsilon>0
都要小。您可以添加一个中断点(通常在迭代~#16处),尝试其他方法来写入数据,但您到达那里的可能性非常小。 - amit