執行緒基礎之遺漏和擴充套件部分
這裡我們只是關注了一些多執行緒之間共享變數的簡單使用問題。這些是任何一個寫多執行緒程式的人,都應該熟悉的最基礎的問題。我們忽略了一些其他多執行緒實現提供的工具。它們雖然很少被用到,但是對於你的程式仍然很有必要。
其他鎖型別
大多數環境提供可重入鎖,即被一個單執行緒多次持有,比如java synchronized 塊就有這種鎖的特性行為。通常讀寫鎖也提供這個功能,即一個鎖可以同時被多個“讀”執行緒持有,但只能同時被一個“寫”執行緒持有。
條件變數等
對於一個執行緒等待某個特殊條件符合要求,條件變數時最普遍的機制,比如等待一個共享佇列是不為空的。這些提供wait()呼叫來釋放並且重新獲取一個鎖,掛起執行緒一段時間,直到它被另個執行緒喚醒(”notified” or signalled”)。如果一個執行緒不能被正確喚醒,條件變數很容易引入死鎖到應用程式。因此它們應該被謹慎的運用。但如果我們的關注點只是我們的程式而不是產生的錯誤結果,一個wait(cv, lock
非阻塞鎖獲取
大多數語言或者執行緒庫提供一個trylock()原函式,可以獲得一個鎖,像lock()的功能,或者返回一個錯誤的提示,但它從來不會阻塞,這非常容易被我們的模型容納,我們允許trylock()返回一個錯誤的提示,即使這個鎖是可獲得,或者至少是我們程式碼的原因,雖然這有可能發生。 因為一些微妙的原因這個假設不允許通過程式實現 ,否則可以看出順序一致性的錯覺 ,類似觀察申請鎖時呼叫超時。實際上,不允許在程式碼中濫用trylock(),並且應該去用其他一些原語。
從順序一致性“逃離”
很多語言允許通過侵犯順序一致性來獲取同步變數,即使程式不包含資料競爭。很多平臺用這些來顯著提升效能,以一個更復雜的程式模型為代價,在這裡我們不討論該問題。例如java.util.concurrent.atomic‘s lazySet() (Java 6 +) and weakCompareAndSet() 允許一些實現以和順序一致性違背的方式來進行重排序。C++0x atomic objects 支援記憶體排序限定引數的操作,它們大部分和順序一致性違背。
歷史和致謝
順序一致性概念是被Lamport引入的,How to Make a Multiprocessor Computer that Correctly Executes Multiprocess Programs
最近幾年java和C++0x記憶體模型是明確的基於這種方式實現的。除了這些方面的論文作者,還有主要的貢獻者包括Lawrence Crowl, Doug Lea, Paul McKenney, Clark Nelson, Bratin Saha, and Herb Sutter.
Paul McKenney也發表了一篇“frequently asked questions”文章,內容和這篇文章類似。Sarita Adve在實現章節提供一些內容。我們也借用了Herb Sutter例子。
很多讀者在早期的草稿中提供了有用的評論。Rob Schreiber提供了特殊的擴充套件。