無鎖與等待無關程式設計
無障礙進展(obstruction-free progress)
想像兩個人想在同一塊白板上寫字。如果他們不斷撞到手肘,誰都寫不完一句話。但只要其中一人乾脆退開——停止干擾——另一人就能順利寫完。無障礙(obstruction-free)正好捕捉了這種最弱但仍有用的承諾:任何執行緒只要能單獨執行一陣子、沒有其他人碰那個共享結構,就會完成。
精確地說:一個演算法是無障礙的,是指只要某個執行緒孤立地執行——也就是所有其他執行緒都暫停時——它就在有界步數內完成操作。它對「主動競爭下會發生什麼」隻字不提;兩個無障礙的執行緒可以永遠互相干擾,各自反覆撤銷對方的進展。這就是著名的活結(livelock)失敗模式。無障礙嚴格弱於無鎖:每個無鎖演算法都是無障礙的,但無障礙的演算法可能活結,因而不是無鎖。
為什麼要定義這麼弱的性質?因為它較容易達成,而且它乾淨地把演算法的正確性與它在競爭下的進展分開。無障礙演算法本身是正確的;接著你外掛一個競爭管理器——通常是隨機化的指數退避(exponential backoff)——讓執行緒夠頻繁地互相讓路,在實務上打破活結。軟體交易記憶體(software transactional memory)系統是這個想法早期著名的歸宿:先把演算法做到無障礙,再另外管理競爭。
/* 兩個無障礙的執行緒在競爭下可能永遠來回乒乓: */ 執行緒 A:讀 X、準備更新、CAS 失敗(B 改了 X)、重試…… 執行緒 B:讀 X、準備更新、CAS 失敗(A 改了 X)、重試…… /* 各自單獨都會成功;合在一起若沒有退避管理器可能活結。 */
無障礙僅在孤立時保證進展;競爭由另外的退避或競爭管理器處理。
由強到弱的階層是:等待無關、無鎖、無障礙。三者之中只有無障礙允許活結。
又稱
另見