什麼是放鬆對ThreadMethodOne中的加載變量valA和valB的同步的最正確方法(假設valA和valB沒有錯誤的緩存行共享)?似乎我不應該改變ThreadMethodOne使用memory_order_relaxed來加載valA,因爲編譯器可能會在valB.load之後移動valA.load,因爲valB.load上的memory_order_acquire不能保護valA不會在valB.load之後移動一次這一變化已經完成。它似乎也不能在valB.load上使用memory_order_relaxed,因爲它不再與ThreadMethodTwo中的fetch_add同步。交換項目並放寬valA的負載會更好嗎?C++在兩個不同的變量上使用memory_order_relaxed
這是正確的改變嗎?
nTotal += valB.load(std::memory_order_acquire);
nTotal += valA.load(std::memory_order_relaxed);
縱觀上編譯器Explorer中的結果似乎顯示ThreadMethodOne相同的代碼生成時使用memory_order_relaxed對於任何瓦拉或值Valb,即使我不換的指令的順序。我還看到ThreadMethodTwo中的memory_order_relaxed仍編譯爲與memory_order_release相同。將memory_order_relaxed更改爲以下行似乎使它成爲非鎖定添加'valA.store(valA.load(std :: memory_order_relaxed)+ 1,std :: memory_order_relaxed);'但我不知道這是否更好。
全部程序:
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <atomic>
#include <unistd.h>
bool bDone { false };
std::atomic_int valA {0};
std::atomic_int valB {0};
void ThreadMethodOne()
{
while (!bDone)
{
int nTotal {0};
nTotal += valA.load(std::memory_order_acquire);
nTotal += valB.load(std::memory_order_acquire);
printf("Thread total %d\n", nTotal);
}
}
void ThreadMethodTwo()
{
while (!bDone)
{
valA.fetch_add(1, std::memory_order_relaxed);
valB.fetch_add(1, std::memory_order_release);
}
}
int main()
{
std::thread tOne(ThreadMethodOne);
std::thread tTwo(ThreadMethodTwo);
usleep(100000);
bDone = true;
tOne.join();
tTwo.join();
int nTotal = valA.load(std::memory_order_acquire);
nTotal += valB.load(std::memory_order_acquire);
printf("Completed total %d\n", nTotal);
}
更好的樣品離開原來的一個,因爲它是一個在評論中寫
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <atomic>
#include <unistd.h>
std::atomic_bool bDone { false };
std::atomic_int valA {0};
std::atomic_int valB {0};
void ThreadMethodOne()
{
while (!bDone)
{
int nTotalA = valA.load(std::memory_order_acquire);
int nTotalB = valB.load(std::memory_order_relaxed);
printf("Thread total A: %d B: %d\n", nTotalA, nTotalB);
}
}
void ThreadMethodTwo()
{
while (!bDone)
{
valB.fetch_add(1, std::memory_order_relaxed);
valA.fetch_add(1, std::memory_order_release);
}
}
int main()
{
std::thread tOne(ThreadMethodOne);
std::thread tTwo(ThreadMethodTwo);
usleep(100000);
bDone = true;
tOne.join();
tTwo.join();
int nTotalA = valA.load(std::memory_order_acquire);
int nTotalB = valB.load(std::memory_order_relaxed);
printf("Completed total A: %d B: %d\n", nTotalA, nTotalB);
}
爲什麼你覺得你需要放鬆點餐呢? – GManNickG
這更多是爲了更好地理解這個話題。 –
https://www.youtube.com/watch?v=c1gO9aB9nbs 關於這個問題的權威性討論。 –