2010-03-04 2 views
10

스레드 안전 C++ 약한 포인터 템플릿 클래스를 개발하려는 시도에서 개체가 아직 살아 있는지 나타내는 플래그를 확인해야합니다. 그렇다면 개체의 참조 횟수를 증가시키고 두 단계를 원자 적으로 수행해야합니다.원자 적으로 비교 및 ​​증분하는 방법은 무엇입니까?

_InterlockedCompareExchange() 및 _InterlockedIncrement()와 같이 컴파일러에서 제공하는 내장 함수의 존재를 알고 있습니다. 하지만 내가 원하는 것은 interlockedCompareIncrement() 함수입니다. 적어도 Windows x86 플랫폼에서는 다른 기본 요소를 사용하여이 내장 함수를 시뮬레이션하는 효율적인 방법이 있습니까?

+0

은 Windows에있는 경우 , 당신은 이렇게 말해야한다. – Gabe

답변

7

value이 플래그 변수라고 가정합니다. volatile으로 선언해야합니다.

long curvalue; 
long newvalue; 

do 
{ 
    curvalue = value; 
    newvalue = curvalue + 1; 
} 
while(_InterlockedCompareExchange(&value, newvalue, curvalue) != curvalue); 

당신이 당신이 newvalue을 계산하는 데 적용되는 작업을 변경하여 필요한 연산의 어떤 종류에 일반화 할 수시피.

동시에 두 값을 비교하려는 경우 가장 좋은 방법은 두 값을 단일 변수로 묶은 다음 해당 단일 변수에서 연산하는 것입니다. 참조 횟수와 결합 된 플래그를 사용 중이므로 value의 최하위 비트를 '활성'플래그로 사용하고 한 번에 2 씩 증가/감소를 권장합니다. 이를 통해 플래그와 참조 카운트 모두를 단일 32 비트 변수로 인코딩 할 수 있습니다.

+0

그것은 내가 찾고있는 것으로 보인다, 나는 그것에 깊이 보일 것이다. –

+0

+1 : 원자 IncIfNot 함수를 찾고있었습니다. 이것은 루프와 _InterlockedCompareExchange()로 작성하는 것도 가능합니다! – mmmmmmmm

0

C++을 사용하고 있으므로 직접 어셈블리 코드를 작성할 수 있습니다.

아마도 이것은 당신이 당신의 라이브러리가 여러 CPU하거나 CPU가 제공하는 하드웨어 지원을 사용해야하는 다중 코어 시스템에서 실행하려면 Implement atomic increment using atomic swap?