多執行緒程式設計中 Volatile 的固有限制
在多執行緒程式設計領域,同步對共享資料的存取至關重要。一種方法涉及利用 volatile 關鍵字來確保變數值的保存。然而,最近的一次討論引起了人們對 volatile 在這種情況下的功效的擔憂。
什麼是 Volatile?
Volatile 宣告的變數不應從程式。這確保編譯器不會將值緩存在寄存器中,而是在每次訪問時從記憶體中獲取它。它最初旨在與硬體暫存器或 I/O 操作一起使用,但經常用於多執行緒程式設計情況。
多執行緒中 Volatile 的挑戰
不幸的是,易失性在多執行緒上下文中使用時有限制。雖然它保證對易失性變數的讀取和寫入立即發生,並且相對於其他易失性存取以正確的順序進行,但它並不能阻止圍繞易失性存取對非揮發性記憶體存取進行重新排序。
考慮一個全域變數 foo宣告為 volatile,由多個執行緒共用。一個線程以原子方式設定 foo,而另一個線程則讀取它。易失性聲明確保寫入和讀取操作不會被最佳化。但是,編譯器仍可能對其他記憶體操作進行重新排序,例如相對於揮發性操作載入非揮發性變數。
解:記憶體屏障與原子變數
為了防止重新排序,需要記憶體屏障。它們指示編譯器和 CPU 確保不會跨過屏障重新排序記憶體存取。在寫入易失性變數之後放置記憶體屏障可以防止後續非揮發性讀取相對於揮發性寫入的重新排序。
但是,由於記憶體屏障也保證執行所有掛起的讀取和寫入,因此它們本質上是提供與 volatile 相同的功能。因此,在使用記憶體屏障時, volatile 關鍵字就變得不必要了。
C 中的現代替代方案:原子變數
在C 11 中,原子變數(std::atomic
以上是Volatile真的能解決多執行緒同步問題嗎?的詳細內容。更多資訊請關注PHP中文網其他相關文章!