2012-12-03 1 views
4

Boost 1.5.1 소스에서 smart_ptr\detail\atomic_count_win32.hpp 아래는 깔끔한 작은 원자 참조 카운터 boost::detail::atomic_count입니다.왜 참조 카운터 값을 휘발성 참조 상수로 읽습니까?

class atomic_count 
{ 
public: 

// ... 

operator long() const 
{ 
    return static_cast<long const volatile &>(value_); 
} 

private: 
long value_; 

왜 카운터 값이 참조 - 투 - 어 - 휘발성 일정한 길이 (long const volatile&)에 캐스팅 : 라인 48에

, 그들은 내가 호기심이 약 해요 캐스트를합니까?

+0

'value_'의 유형은 무엇입니까? –

+0

@ slavik262 : 정규 (CV가 아닌 정규화 된) 'long'입니다. – ruakh

+0

무엇이 나를 공격할까요? [이전 버전] (http://www.boost.org/doc/libs/1_32_0/boost/detail/atomic_count_win32.hpp) – UmNyobe

답변

5

MSVC 그들이 획득하고 의미를 풀어주는 extension on volatile variables 지금은 사용되지 않는 제공 (메모리 멀티 스레드 프로그래밍과 관련하여 보증을 주문.)

이 캐스팅이주는 변수에이 확장을 "수"읽기 취득 의미 (발생 가능한 릴리스 쓰기와 일치시키기 위해). 다시 말하지만, 이것은 비표준입니다. C++ 11 코드에서는 std::atomic<>을 사용해야합니다.

boost::shared_ptr은 멀티 스레드 (공유) 사용에서 shared_ptr<T>에 대한 정확성을 보장하므로 필요합니다. 이것은 lock-free 카운터의 구현입니다.

(이 확장은 필요한 순서 및 가시성 보증을 제공 할 수 있지만 원 자성을 보장하지는 못하지만 Win32에서는 실행되는 플랫폼에 의해 암시 적으로 보장됩니다. 정렬 된 워드 크기의 정수 읽기 및 쓰기는 플랫폼별로 원자가입니다.

시작하기 전에 새싹을 찍으려면이 확장자가 없으면 volatile은 다중 스레드 프로그래밍에 유용하지 않습니다. 시도조차하지 마십시오. 이 확장 기능은 더 이상 사용되지 않으므로 가능한 경우 사용하지 않는 것이 좋습니다.

1

x86 플랫폼에서 기본 너비의 정렬 된 값의 경우 충분하다고 알려져 있습니다.

  1. 변수는 16 진수 값 0000FFFF 있습니다

    그들이 피하려고하는 문제는 이것이다.

  2. 스레드 A는 값 읽기를 시작하고 0000xxxx 부분을 가져옵니다.

  3. 스레드 B는 0000FFFF에서 00010000으로 값을 증가시킵니다.

  4. 스레드 A는 아직 값을 읽지 못하고 xxxx0000 부분을 읽지 못했습니다.

  5. 스레드 A는 이제 00000000 값을 읽습니다!

이것은 단어 찢어짐이라고합니다. 그러나 x86에서 기본 너비가 정렬 된 유형의 경우에는 발생하지 않는 것으로 알려져 있습니다. 따라서 volatile을 통한 단순한 캐스트 (문제가있는 컴파일러 최적화를 피하는 것으로 알려져 있음) 만 있으면됩니다.

이것은 일반적인 진리는 아닙니다. 이것은 단지 플랫폼의 속성 일뿐입니다. 이것은 이식성이없는 코드입니다.

+1

나는 데이브 한가지를 인정해야한다. 나는 충분하지 못하다. – UmNyobe

+0

나는 인라인 어셈블리 나 컴파일러 내장 함수와 같은 더 공격적인 것은 필요 없다는 것을 의미합니다. (일부 세부 사항으로 답변을 업데이트했습니다.) –

+2

원자력은 요구 사항의 절반에 지나지 않으며 주문 및 가시성도 해결해야합니다. 이를 위해서는 MSVC가 확장 기능으로 '휘발성 (volatile)'을 제공하는 플랫폼 (x86 플랫폼과 같이 강력하게 주문한 플랫폼)이나 메모리 펜스 (fences)와 같은 암시 적 보증이 필요합니다. 그런데 목표 ("원 자성")를 언급하지 않고 "충분"하고 "필요한 모든 것"이라고 말하기 때문에 대답은 혼란 스럽습니다 (UmNyobe가 암시하는 말). – GManNickG