측정되는 업데이트 및 일부 자산의 평균을 반환하는 두 가지 기능이 있습니다 말 평균 계산하는 의미를 획득 :출시
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
의 취득 부하 Update()
에 의해 수행 m_accumulatedValue
에 어떤 변화가 스레드 호출하여 볼 수 보장하는 동시에 그 전에 m_accumulatedValue
의 부하의 재정렬 및 금지 GetAverage()
m_count
로 변경하면 상점에서 수행 한 m_cout
은 Update()
으로 출시 주문이 있습니다.
내가 방금 말한 것이 맞습니까?
GetAverage()
(Update()
에 대한 호출의 비 동시성 보장과 함께) 항상 올바른 대답을 반환합니까? 아니면 계산 된 평균값을 다른 값보다 "더 업데이트 된"값으로 반환하는 방법이있을 수 있습니까?
m_accumulatedValue
은 원자 일 필요가 있습니까?
'memory_order_relaxed'는 다른 스레드가 새로운 값을 보지 못하게하지 않으며, 단지 그것을 요구하지 않습니다.따라서 여전히 경쟁 조건이 존재할 수 있습니다. –
메모리 순서 의미를 제외하고이 코드는 손상되었습니다. 하나의 가능한 실행 순서는 한 스레드가'm_accumulatedValue'에 추가 한 다음 다른 스레드가'm_accumulatedValue' ** 및 **'m_count'를 읽으면 첫 번째 스레드는'm_count'를 업데이트합니다. 두 번째 스레드가 계산 한 평균은 잘못 될 것입니다. –
번호. 아마도. 상호 배제를 사용하지 않는 이유는 무엇입니까? – jotik