C++學習之STL執行緒安全性考慮
阿新 • • 發佈:2019-01-08
條款12:對STL容器執行緒安全性的期待現實一些
標準C++的世界是相當保守和陳舊的。在這個純潔的世界,所有可執行檔案都是靜態連結的。不存在記憶體對映檔案和共享記憶體。沒有視窗系統,沒有網路,沒有資料庫,沒有其他程序。在這種情況下,當發現標準沒有提到任何關於執行緒的東西時你不該感到驚訝。你對STL的執行緒安全有的第一個想法應該是它將因實現而不同。
當然,多執行緒程式是很普遍的,所以大部分STL廠商努力使他們的實現線上程環境中可以正常工作。但是,即使他們做得很好,大部分負擔仍在你肩上,而理解為什麼會這樣是很重要的。STL廠商只能為你做一些可以減少你多執行緒的痛苦的事情,你需要知道他們做了什麼。
在STL容器(和大多數廠商的願望)裡對多執行緒支援的黃金規則已經由SGI定義,並且在它們的STL網站[21]上釋出。大體上說,你能從實現裡確定的最多是下列內容:
多個讀取者是安全的。多執行緒可能同時讀取一個容器的內容,這將正確地執行。當然,在讀取時不能有任何寫入者操作這個容器。
對不同容器的多個寫入者是安全的。多執行緒可以同時寫不同的容器。
就這些了,那麼讓我解釋你可以期望的是什麼,而不是你可以確定的。有些實現提供這些保證,但是有些不。
寫多執行緒的程式碼很難,很多程式設計師希望STL實現是完全執行緒安全的。如果是那樣,程式設計師可以不再需要自己做並行控制。毫無疑問這將帶來很多方便,但這也非常難實現。一個庫可能試圖以下列方式實現這樣完全執行緒安全的容器:
在每次呼叫容器的成員函式期間都要鎖定該容器。
在每個容器返回的迭代器(例如通過呼叫begin或end)的生存期之內都要鎖定該容器。
在每個在容器上呼叫的演算法執行期間鎖定該容器。(這事實上沒有意義,因為,正如條款32所解釋的,演算法沒有辦法識別出它們正在操作的容器。不過,我們將在這裡檢驗這個選項,因為它的教育意義在於看看為什麼即使是可能的它也不能工作。)
標準C++的世界是相當保守和陳舊的。在這個純潔的世界,所有可執行檔案都是靜態連結的。不存在記憶體對映檔案和共享記憶體。沒有視窗系統,沒有網路,沒有資料庫,沒有其他程序。在這種情況下,當發現標準沒有提到任何關於執行緒的東西時你不該感到驚訝。你對STL的執行緒安全有的第一個想法應該是它將因實現而不同。
當然,多執行緒程式是很普遍的,所以大部分STL廠商努力使他們的實現線上程環境中可以正常工作。但是,即使他們做得很好,大部分負擔仍在你肩上,而理解為什麼會這樣是很重要的。STL廠商只能為你做一些可以減少你多執行緒的痛苦的事情,你需要知道他們做了什麼。
在STL容器(和大多數廠商的願望)裡對多執行緒支援的黃金規則已經由SGI定義,並且在它們的STL網站[21]上釋出。大體上說,你能從實現裡確定的最多是下列內容:
多個讀取者是安全的。多執行緒可能同時讀取一個容器的內容,這將正確地執行。當然,在讀取時不能有任何寫入者操作這個容器。
對不同容器的多個寫入者是安全的。多執行緒可以同時寫不同的容器。
就這些了,那麼讓我解釋你可以期望的是什麼,而不是你可以確定的。有些實現提供這些保證,但是有些不。
寫多執行緒的程式碼很難,很多程式設計師希望STL實現是完全執行緒安全的。如果是那樣,程式設計師可以不再需要自己做並行控制。毫無疑問這將帶來很多方便,但這也非常難實現。一個庫可能試圖以下列方式實現這樣完全執行緒安全的容器:
在每次呼叫容器的成員函式期間都要鎖定該容器。
在每個容器返回的迭代器(例如通過呼叫begin或end)的生存期之內都要鎖定該容器。
在每個在容器上呼叫的演算法執行期間鎖定該容器。(這事實上沒有意義,因為,正如條款32所解釋的,演算法沒有辦法識別出它們正在操作的容器。不過,我們將在這裡檢驗這個選項,因為它的教育意義在於看看為什麼即使是可能的它也不能工作。)