2011-08-31 106 views
4

我需要一個數據結構實現這些有點不尋常(據我所知)要求:中斷安全組掃描

  1. 支持的操作是插入(套,件),刪除(套,條)和FORALL(套,操作)
  2. 插入和刪除是罕見的操作。該集合通常只包含一個項目。
  3. 在C中實現必須是可行的;特別是,你沒有垃圾收集。
  4. ForAll必須安全,可以從異步信號處理程序執行,其調用可能會中斷Insert或Delete。

當然,最後的要求是殺手。我有一個玩具實現,它會在全局鏈表上引發一個全局鎖,但是如果信號處理程序中斷了一個關鍵部分,那麼就會發生死鎖。我知道在信號處理程序中執行任意代碼的所有問題;爲了解決這個問題,我們着重討論如何使ForAll崩潰和死鎖安全,因爲它可能會中斷Insert或刪除)。

回答

6

如果這些集合通常很小,這樣在插入和刪除方法中列表的線性搜索速度足夠快,那麼您可以使用使用比較和交換的無鎖鏈接列表實現。搜索給出了一些解釋和例子。

http://www.google.com/search?q=lock+free+linked+list

所有更新的列表作爲原子操作(比較並交換),因此中斷不會引起問題進行。

+0

謝謝,但我希望得到更具體和有針對性的答案。我已經閱讀了其中的幾篇文章。他們專注於針對*對方進行插入和刪除無鎖操作,並忽略ForAll。我完全可以很好地將Insert和Delete鎖在一起(事實上,做任何事情似乎都是不必要的複雜性,因爲列表非常短),但這對ForAll沒有幫助。 – zwol

+1

我想我可能會錯過一些東西,但它看起來像http://reference.kfupm.edu.sa/content/l/o/lock_free_linked_lists_using_compare_and_3368.pdf中的論文很有效地解決了遍歷問題。 –

+0

我接受這個,因爲它在一般情況下是正確的答案,但爲了記錄,我最終做的是在插入和刪除操作中調用'sigprocmask',以防止它們與信號處理程序競爭。 – zwol

1

我確信Jim的方法很好,但是對於小集和偶爾更新,您可能會更樂意實現最簡單的軟件事務內存形式。

  1. 讀取指向當前版本結構的指針。
  2. 製作該版本的副本並進行更新。
  3. 比較和交換的更新。如果CAS失敗,請返回步驟1.

異步掃描是微不足道的 - 讀取和去除。如果沒有垃圾回收,你需要使用Jim鏈接的文件中的SafeRead和Release之類的東西。

+0

如果我沒有弄錯,這是[Read-Copy-Update](http://en.wikipedia。org/wiki/Read-copy-update) – Hasturkun

+0

在我工作的環境中,這是不可行的,因爲無法知道RCU「寬限期」何時過去。 – zwol