문제

어떻게 구현합니까? 효율적이고 스레드에 안전한 참조 카운팅 시스템 C++ 프로그래밍 언어의 X86 CPU에서?

나는 항상 문제에 부딪힌다. 원자적이지 않은 중요한 작업, 사용 가능한 X86 인터록 작업은 참조 카운팅 시스템을 구현하는 데 충분하지 않습니다.

다음 문서에서는 이 주제를 다루지만 특별한 CPU 지침이 필요합니다.

http://www.ddj.com/architect/184401888

도움이 되었습니까?

해결책

요즘에는 Boost/TR1 shared_ptr<> 스마트 포인터를 사용하여 참조 계산 참조를 유지할 수 있습니다.

훌륭하게 작동합니다.소란도 없고 소란도 없습니다.shared_ptr<> 클래스는 참조 카운트에 필요한 모든 잠금을 처리합니다.

다른 팁

VC++에서는 다음을 사용할 수 있습니다. _Interlocked비교교환.

do
   read the count
   perform mathematical operation
   interlockedcompareexchange( destination, updated count, old count)
until the interlockedcompareexchange returns the success code.

다른 플랫폼/컴파일러에서는 MS의 _InterlockedCompareExchange가 노출하는 LOCK CMPXCHG 명령에 대해 적절한 내장 함수를 사용하십시오.

엄밀히 말하면, 순수 C++로 스레드로부터 안전한 코드를 작성할 수 있으려면 C++0x까지 기다려야 합니다.

지금은 Posix를 사용하거나 비교 및 ​​교환 및/또는 연동된 증가/감소에 대한 자체 플랫폼 독립적 래퍼를 만들 수 있습니다.

Win32 InterlockedIncrementAcquire 및 InterlockedDecrementRelease(재주문이 가능한 플랫폼을 안전하게 보호하고 싶으므로 동시에 메모리 장벽을 발행해야 하는 경우) 또는 InterlockedIncrement 및 InterlockedDecrement(x86을 유지할 것이라고 확신하는 경우)는 원자성이고 일을 해라.

즉, Boost/TR1 shared_ptr<>이 이 모든 것을 처리하므로 직접 구현할 필요가 없는 한 이를 고수하기 위해 최선을 다할 것입니다.

잠금은 매우 비용이 많이 들고, 스마트 포인터 사이에서 객체를 건네줄 때마다 발생한다는 점을 명심하세요. 객체가 현재 하나의 스레드에 의해 소유되어 있는 경우에도(스마트 포인터 라이브러리는 이를 알지 못합니다).

이를 감안할 때 여기에 적용할 수 있는 경험 법칙이 있을 수 있습니다(수정되어서 기쁘네요!)

다음 사항이 귀하에게 해당되는 경우:

  • 소멸자를 작성하기 어려운(또는 설계상 STL 스타일 값 의미 체계가 부적절할 수 있는) 복잡한 데이터 구조가 있으므로 이를 수행하기 위한 스마트 포인터가 필요합니다.
  • 이러한 개체를 공유하는 여러 스레드를 사용하고 있으며
  • 정확성뿐만 아니라 성능에도 관심이 있습니다.

...그러면 실제 가비지 수집이 더 나은 선택이 될 수 있습니다.GC는 성능 면에서 평판이 좋지 않지만 모두 상대적입니다.나는 이것이 스마트 포인터를 잠그는 것과 매우 유리하다고 생각합니다.이는 CLR 팀이 참조 카운팅을 사용하는 대신 진정한 GC를 선택한 이유 중 중요한 부분이었습니다.보다 이 기사, 특히 계산이 진행 중인 경우 참조 할당이 무엇을 의미하는지에 대한 이 뚜렷한 비교는 다음과 같습니다.

참조 계산 없음:

a = b;

참조 계산:

if (a != null)
    if (InterlockedDecrement(ref a.m_ref) == 0)
            a.FinalRelease();

if (b != null)
    InterlockedIncrement(ref b.m_ref);

a = b;

명령 자체가 원자적이지 않은 경우 해당 변수를 업데이트하는 코드 섹션을 중요한 섹션으로 만들어야 합니다.

즉. 일부 잠금 방식을 사용하여 다른 스레드가 해당 코드 섹션에 진입하는 것을 방지해야 합니다.물론 잠금은 원자적이어야 하지만 pthread_mutex 클래스 내에서 원자 잠금 메커니즘을 찾을 수 있습니다.

효율적인 문제:pthread 라이브러리는 최대한 효율적이며 OS에 대한 뮤텍스 잠금이 원자적임을 보장합니다.

비싸:아마.그러나 보증이 필요한 모든 것에는 비용이 따릅니다.

해당 ddj 기사에 게시된 특정 코드는 스마트 포인터 사용 시 버그를 설명하기 위해 추가 복잡성을 추가하고 있습니다.

특히, 다른 스마트 포인터에 대한 할당에서 스마트 포인터가 변경되지 않을 것이라고 보장할 수 없다면 잘못 수행했거나 처음부터 매우 신뢰할 수 없는 작업을 수행하고 있는 것입니다.스마트 포인터가 다른 스마트 포인터에 할당되는 동안 변경될 수 있다면 할당을 수행하는 코드가 처음부터 의심되는 스마트 포인터를 소유하지 않음을 의미합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top