[英]C/C++ arrays with threads - do I need to use mutexes or locks?
我是使用線程的新手,並且已經閱讀了很多關於如何共享和保護數據的內容。 但我也沒有真正掌握使用互斥鎖和鎖來保護數據。
下面是我將要解決的問題的描述。 需要注意的重要一點是,這將是時間緊迫的,所以我需要盡可能地減少開銷。
我有兩個固定大小的雙數組。
第一個數組將為后續計算提供數據。 線程將從它讀取值,但它永遠不會被修改。 某個元素可能會在某個時間被任何線程讀取。
第二個數組將用於存儲線程執行的計算結果。 這個數組的一個元素只會被一個線程更新,並且可能只有一次當結果值
是寫給它的。
我的問題是:
每次訪問只讀數組中的數據時,我真的需要在線程中使用互斥鎖嗎? 如果是這樣,你能解釋一下原因嗎?
當線程寫入結果數組時,我是否需要在線程中使用互斥鎖,即使這將是唯一寫入該元素的線程?
我應該使用原子數據類型嗎,如果我這樣做會不會有任何顯着的時間開銷?
此類問題的許多答案似乎是 - 不,如果您的變量對齊,則不需要互斥鎖。 我在這個例子中的數組元素會對齊,還是有什么方法可以確保它們對齊?
該代碼將在 64 位 Linux 上實現。 我計划使用 Boost 庫進行多線程處理。
幾天來我一直在仔細考慮這個問題,並在整個網絡上查看,一旦發布,答案和清晰的解釋在幾秒鍾內就回來了。 有一個“接受的答案”,但所有的答案和評論都同樣有幫助。
- 每次訪問只讀數組中的數據時,我真的需要在線程中使用互斥鎖嗎? 如果是,你能解釋一下原因嗎?
不會。因為數據永遠不會被修改,所以不會有同步問題。
- 當線程寫入結果數組時,我是否需要在線程中使用互斥鎖,即使這將是唯一寫入該元素的線程?
要看。
在任何情況下,請注意不要由不同的線程大量寫入相鄰的內存位置。 這可能會破壞性能。 參見“虛假共享”。 考慮到,您可能沒有很多內核,因此沒有很多線程,並且您說寫入僅完成一次,但這可能不會成為一個重大問題。
- 我應該使用原子數據類型嗎,如果我這樣做會不會有任何重要的時間開銷?
如果您使用鎖(互斥),則不需要原子變量(並且它們確實有開銷)。 如果不需要同步,則不需要原子變量。 如果您需要同步,那么在某些情況下可以使用原子變量來避免鎖定。 在哪些情況下你可以使用原子而不是鎖......我認為這更復雜,超出了這個問題的范圍。
鑒於您在評論中的情況描述,似乎根本不需要同步,因此不需要原子或鎖。
- ...在這個例子中我的數組元素是否會對齊,或者有什么方法可以確保它們對齊?
正如 Arvid 所指出的,您可以使用 c++11 中引入的alginas關鍵字請求特定對齊。 在 c++11 之前,您可以求助於編譯器特定的擴展: https : //gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Variable-Attributes.html
在給定的兩個條件下,不需要互斥鎖。 請記住,每次使用互斥鎖(或任何同步構造)都是一種性能開銷。 所以你想盡可能地避免它們(當然不影響正確的代碼)。
不。不需要互斥體,因為線程只讀取數組。
不可以。由於每個線程只寫入不同的內存位置,因此不可能出現競爭條件。
不。這里不需要對對象進行原子訪問。 事實上,使用原子對象可能會對性能產生負面影響,因為它會阻止優化的可能性,例如重新排序操作。
只有在共享資源上的數據被修改時才需要使用鎖。 例如,如果一些線程用於寫入數據而一些用於讀取數據(在這兩種情況下都來自同一資源),那么您只需要在寫入完成時鎖定。 這是為了防止所謂的“種族”。
當您制作在共享資源上操作數據的程序時,谷歌上有很好的種族信息。
你走在正確的軌道上。
1)對於第一個數組(只讀),您不需要為其使用互斥鎖。 由於線程只是讀取而不是更改數據,因此線程無法破壞另一個線程的數據
2)我對這個問題有點困惑。 如果您知道線程 1 只會將元素寫入數組插槽 1,而線程 2 只會寫入數組插槽 2,那么您不需要互斥鎖。 但是我不確定你是如何實現這個屬性的。 如果我的上述陳述不適合您的情況,您肯定需要一個互斥鎖。
3) 鑒於原子的定義:
原子類型是封裝一個值的類型,該值的訪問保證不會引起數據競爭,並且可用於同步不同線程之間的內存訪問。
重點說明,互斥鎖是原子的,這意味着只需要 1 條匯編指令即可獲取/釋放鎖。 如果需要 2 個組裝指令來抓取/釋放鎖,那么鎖就不是線程安全的。 例如,如果線程 1 嘗試獲取鎖並被切換到線程 2,線程 2 將獲取鎖。
使用原子數據類型會減少你的開銷,但不會顯着。
4)我不確定你如何確保你的變量是內襯的。 由於線程可以在您的程序中隨時切換(您的操作系統確定線程何時切換)
希望這可以幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.