[英]How to test the behavior of std::memory_order_relaxed?
我已閱讀std::memory_order_relaxed的文檔。
放寬排序的解釋之一是......
// Thread 1: r1 = y.load(memory_order_relaxed); // A x.store(r1, memory_order_relaxed); // B // Thread 2: r2 = x.load(memory_order_relaxed); // C y.store(42, memory_order_relaxed); // D
對此的解釋是......
[它] 允許產生
r1 == r2 == 42
。 特別是,如果 D 在線程 2 中的 C 之前完成,則可能會發生這種情況,這是由於編譯器重新排序或在運行時。
我已經理解了解釋,並嘗試在我的電腦上測試如下代碼:
std::atomic<int> x = {0};
std::atomic<int> y = {0};
int r1, r2;
void task1() {
// Thread 1:
r1 = y.load(memory_order_relaxed); // A
x.store(r1, memory_order_relaxed); // B
}
void task2() {
// Thread 2:
r2 = x.load(memory_order_relaxed); // C
y.store(42, memory_order_relaxed); // D
}
int main()
{
std::thread t2 (task2);
std::thread t1 (task1);
t1.join();
t2.join();
cout << "r1: " << r1
<< "\nr2: " << r2 << endl;
return 0;
}
此代碼的結果永遠不會r1 == r2 == 42
,據說這是該文檔中的一種可能行為。
這段代碼有什么問題嗎? 或者,有什么誤解嗎?
或者,有什么誤解嗎?
是的,有一個。 std::memory_order_relaxed
在您的程序中允許的內容是針對架構的實現(編譯器),以生成可能觀察到副作用r1 == r2 == 42
。
實現不必產生這樣的程序,這樣的程序也不必產生副作用; 無論如何,這是一個可能的結果。
如何測試 std::memory_order_relaxed 的行為?
我看不到這個問題的一般解決方案。 您只能檢查您觀察到的副作用是否與std::memory_order_relaxed
的規格相匹配。
您的代碼有點幼稚,因為當第二個線程開始時,第一個線程可能已經完成。 線程需要真正並發地運行這些代碼段。
要使r1 == r2 == 42
為真,它需要將加載C
重新排序到存儲D
,x86 不會在當前存儲之后重新排序加載,因此您可能永遠不會在此平台上觀察到這種重新排序(除非編譯器重新排序) C
與D
)。
另一方面,ARM 和 PowerPC 的內存模型較弱。 請參閱運行時內存排序表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.