が測定されている更新し、いくつかのプロパティの平均を返すための2つの機能があると言うの平均計算するセマンティクスを取得:リリース
void Class::Update(int delta)
{
m_accumulatedValue += delta;
++ m_count;
}
double Class::GetAverage()
{
return m_accumulatedValue/(double)m_count;
}
は今、彼らはスレッドとマルチスレッド環境で実行するように変更する必要があるとしいずれかのスレッドがそれらのいずれかを実行するように要求することができるプール - つまり、実行中のスレッドは、それらの一つ一つが毎回異なるものになります
std::atomic<int> m_accumulatedValue;
std::atomic<int> m_count;
// ...
void Class::Update(int delta)
{
m_accumulatedValue.fetch_add(delta , std::memory_order_relaxed);
m_count.fetch_add(1 , std::memory_order_release);
}
double Class::GetAverage()
{
auto count = m_count.load(std::memory_order_acquire);
auto acc = m_accumulatedValue.load(std::memory_order_relaxed);
return acc/(double)count;
}
私は取得を理解し、メモリを解放しようとしています注文。
同じオブジェクトにUpdate()
の同時呼び出しはありませんが、Update()
とGetAverage()
の同じオブジェクトに対する同時呼び出しである可能性があります。私が読んだ何のため
、GetAverage()
でm_count
の取得負荷が同時に前m_accumulatedValue
との負荷の並べ替えを禁止保証Update()
によって行わm_accumulatedValue
への変更は、スレッドの呼び出しによって表示されていることGetAverage()
への変更が一度見られる場合は、m_cout
で行われた店舗ではUpdate()
がリリース注文しています。
私はちょうど正しいと言いましたか?
GetAverage()
(Update()
への呼び出しの並行性が保証されています)は常に正しい答えを返しますか?または、計算された平均値を、「更新された」値のうちのいくつかを他のものよりも戻す方法がありますか?
m_accumulatedValue
はすべて原子である必要がありますか?
'memory_order_relaxed'は、他のスレッドが新しい値を見るのを禁じていませんが、それだけでは必要ありません。だからまだ競争状態になる可能性があります。 –
メモリオーダーセマンティクスとは別に、このコードは壊れています。実行可能な命令の1つは、あるスレッドが 'm_accumulatedValue'に追加し、別のスレッドが' m_accumulatedValue' **と** 'm_count'を読み込むと、最初のスレッドは' m_count'を更新します。 2番目のスレッドによって計算された平均は間違っています。 –
No.いいえ、なぜ相互排除を使用しないのですか? – jotik