このようなロックフリーのデータ構造を構築できるさまざまなプリミティブが利用可能です。たとえば、次のコードをアトミックに実行するコンペア アンド スワップ (略して CAS):
CAS(x, o, n)
if x == o:
x = n
return o
else:
return x
この操作により、アトミックな更新を行うことができます。たとえば、要素をソートされた順序で格納し、新しい要素を挿入したり、要素が既に存在するかどうかを確認したりできる、非常に単純な連結リストを考えてみましょう。検索操作は以前と同じように機能します。要素が見つかるか、クエリよりも大きな要素が見つかるまで、すべてのリンクをトラバースします。挿入にはもう少し注意が必要です。次のように機能します。
insert(lst, x)
xn = new-node(x)
n = lst.head
while True:
n = find-before(n, x)
xn.next = next = n.next
if CAS(n.next, next, x) == next:
break
find-before(n,x)
x
順序で先行する要素を見つけるだけです。もちろん、これは単なるスケッチです。削除をサポートしたい場合、事態はさらに複雑になります。Herlihy と Shavit の「The Art of Multiprocessor Programming」をお勧めします。また、同じモデルを実装するデータ構造を切り替えてロックフリーにすることは、多くの場合有利であることも指摘しておく必要があります。たとえば、 に相当するものを実装したい場合std::map
、赤黒木でそれを行うのは面倒ですが、スキップ リストの方がはるかに扱いやすいです。