메모리 장벽으로 인해 읽기가 최신 값을 볼 수 없다는 것은 당연합니다. 그것이하는 일은 단일 쓰레드와 쓰레드 사이에서 오퍼레이션 간의 순서를 강제하는 것입니다.
예를 들어, 스레드 A가 일련의 저장소를 수행 한 다음 플래그 위치에 최종 저장하기 전에 릴리스 장벽을 실행하고 스레드 B가 플래그 위치에서 읽고 그런 다음 다른 값을 읽기 전에 획득 장벽을 실행하면 다른 변수는 스레드 A에 의해 저장된 값이됩니다 물론
// initially x=y=z=flag=0
// thread A
x=1;
y=2;
z=3;
release_barrier();
flag=1;
// thread B
while(flag==0) ; // loop until flag is 1
acquire_barrier();
assert(x==1); // asserts will not fire
assert(y==2);
assert(z==3);
을, 당신은 부하가 flag
에 저장할 수 있는지 확인해야하는 것은, 간단한로드 및 저장 명령어는 가장 일반적인 CPU에서있는 (원자이다 변수가 적절하게 정렬되어있는 경우). 스레드 B의 while 루프가 없으면 스레드 B는 flag
의 부실 값 (0)을 읽을 수 있으므로 다른 변수에 대해 읽은 값을 보장 할 수 없습니다.
펜스를 사용하여 Dekker의 알고리즘에서 동기화를 시행 할 수 있습니다.
여기 (C++ 0X 원자 변수를 사용하여) C의 예시적인 구현 ++ 같습니다
std::atomic<bool> flag0(false),flag1(false);
std::atomic<int> turn(0);
void p0()
{
flag0.store(true,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
while (flag1.load(std::memory_order_relaxed))
{
if (turn.load(std::memory_order_relaxed) != 0)
{
flag0.store(false,std::memory_order_relaxed);
while (turn.load(std::memory_order_relaxed) != 0)
{
}
flag0.store(true,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
}
std::atomic_thread_fence(std::memory_order_acquire);
// critical section
turn.store(1,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);
flag0.store(false,std::memory_order_relaxed);
}
void p1()
{
flag1.store(true,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
while (flag0.load(std::memory_order_relaxed))
{
if (turn.load(std::memory_order_relaxed) != 1)
{
flag1.store(false,std::memory_order_relaxed);
while (turn.load(std::memory_order_relaxed) != 1)
{
}
flag1.store(true,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
}
std::atomic_thread_fence(std::memory_order_acquire);
// critical section
turn.store(0,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);
flag1.store(false,std::memory_order_relaxed);
}
전체 분석은 다른 CPU가 닿는 경우 http://www.justsoftwaresolutions.co.uk/threading/implementing_dekkers_algorithm_with_fences.html
AFAICT, Dekker 's의 경우, 깃발은 과거에 분명했지만 이제는 비판적인 섹션에 들어가는 것이 안전하다는 것을 알면 충분하지 않습니다. 내가 최신 값을 필요로하는 것처럼 들리며, 당신이 첫 번째 문장에서 말하는 것처럼 당신이 기억 장벽으로 어떻게 그것을 얻는 지 보지 못합니다. –
방금 전에 보았던 것보다 강한 장벽 --- "전체 울타리"가 필요합니다. 나는 Dekker 's가 장벽으로 나중에 보여주기 위해 나의 대답을 갱신 할 것이다. –