2012-07-10 24 views
3

說我有一個偶然的單字節變量。我認爲幾乎所有的系統單字節操作都是原子操作,但如果沒有,請讓我知道。現在,說一個線程更新這個變量。我應該等待多久/準備將此更新顯示在其他線程中?我知道我可以在互斥/鎖定/屏障上進行更新,以確保它在任何地方都是同步的,但我對此很好奇。等待時間可能會有所不同,具體取決於其他線程是否位於不同的處理器/內核上,也可能取決於處理器類型。處理器緩存刷新的頻率如何?

我對這個問題感到懷疑或者我誤解了一些東西嗎?

+4

如果你正在編寫任何依賴這種行爲的代碼,你可能需要考慮一種不同的方法。今天的寬鬆記憶模型可能非常可怕。 – Mysticial 2012-07-10 14:31:54

+1

簡單的答案:不長:) – Brady 2012-07-10 14:32:20

+3

簡短的回答:馬上和永遠之間。它取決於CPU架構,你的其他CPU正在做什麼以及月球的相位。除非您明確地刷新它,否則您將不會看到它的cpu體系結構。另外,要小心考慮將單個字節寫爲「原子」,因爲它們更可能以單位而不是字節爲單位發生,並且根據CPU架構,您可能得不到預期的結果。 – Art 2012-07-10 14:37:29

回答

7

只要調用同步原語/內存屏障(例如pthread_mutex_lock),內存就會同步。除此之外,除非你使用C11原子類型,否則你不應該假設任何同步。

2

在許多體系結構中,處理器將不會刷新緩存,直到其必須爲 - 爲更多需要的數據讓路。

但是,如果線程共享內存空間,那麼您只有一個內核,他們將能夠從緩存中「立即」看到更新。如果它實際上是從CPU寫入內存的。如果編譯器決定將它保存在一個寄存器中,那麼它可能不是這樣,在這種情況下,你的線程將全部擁有自己的「本地」和不正確的副本。如其他人所說,這是一個有趣的問題 - 但同步的正確答案是使用正確的同步原語!

0

在MIPS體系結構中,有一個同步指令用作跨核心的加載存儲障礙,即在執行任何加載之前發生同步之前的所有加載和存儲將在同步之後發生。不確定是否在x86中有等效指令(假設您正在使用的架構)。