2011-02-28 70 views
3

假設我有一個排序,單鏈接的Ñ整數含有沒有重複,ķ線程(其中ķ < < Ñ),每個試圖插入一些列表整數(大於頭節點)放入列表中。單鏈表插入同步

是否有可能插入同步到這樣的列表,例如:

  • 線程只能阻止訪問到它(立即)前一個節點
    (無鎖定「整個列表」)
  • 至多O(k)的互斥體和條件變量可用於
  • 可能發生

沒有搶佔/中斷嗎?

+1

作業?面試問題?你做了什麼試圖自己回答這個問題?這與C有什麼關係? – 2011-02-28 11:34:54

+0

我正在開展一個個人項目,目前我面臨的問題(這更復雜)會降低到我上面要求的水平。我試圖在C中使用pthreads來實現解決方案,這就是爲什麼我添加了c-tag的原因。我應該提供更多的實施細節嗎? – ManRow 2011-02-28 11:43:22

回答

3

首先,如果插入到集合中只是一個非常不頻繁的任務,那麼鏈表就不是一個很好的解決方案 - 因爲找到插入點是一個O(N)操作,即使對於排序列表,因此也會去嚴重縮小比例。

如果您仍然需要做它,它是可以進行插入(不像刪除)成排序列表作爲無鎖操作,具有一定的照顧:

  1. 查找插入點,cur
  2. 創建新節點(分配上/下一個聯動cur/cur->next
  3. 原子OP:compare_and_swap(cur->next, new, new->next);
    如果失敗:if (new->value == next->value) return; // someone beat us to it
    否則:cur = cur->next並重復舞蹈(名單已排序,有人插在我們面前)

嘗試鏈接新節點的結果要麼是我們成功,要麼是有人毆打我們插入相同的節點(在這種情況下,我們沒事 - 它已經在那裏),或者有人插入到間隙中(即現有的N,N+3,我們試過N+1,別人成功N+2),在這種情況下,我們會重試,直到我們成功或找到其他人完成的'我們的'節點。

同步刪除要困難得多;查找RCU(Read-Copy-Update)。

+0

不會定位插入點本身就會導致讀者 - 作者問題?即,如果前面的列表正被修改,我們不能搜索或找到插入點curr。 – ManRow 2011-03-01 01:02:16

+0

您正在測試「早於」,並且該點不會因插入而改變(注意:我不是說_modification_,因爲它包含刪除)。在「原子舞蹈」中,如果有另一個插頁者跑了你,你可能不得不接受插入點,但你永遠不需要退後一步。 – 2011-03-02 08:52:01

+0

@FrankH。我沒有明白爲什麼compareAndSwap有三個參數。在Java中它將是(oldObject,newObject),這裏的第三個參數是什麼? – 2015-12-09 06:10:27