Thread/Windows

[스크랩] Interlocked 함수들..

Binceline 2012. 10. 19. 17:52

출처 : http://silita.tistory.com/10


멀티쓰레드상 한쓰레드가 메모리상에 처리 중 다른 쓰레드가 같은 메모리에 접근하지 못하도록 해야하는데 흔히 크리티컬섹션등의 동기화함수를 쓰게 됩니다. 근데 접근못하게 하는 시간을 최대한 짧게 할 수록 멀티쓰레드를 사용하는 서버의 성능이 향상되게 되죠. 그런 의미에서 쓰레드 세이프하면서 코스트 적은 숫자 증가 방법은 여러모로 활용 가능성이 높습니다. 윈도우에서는 이를 위해 Interlocked 라는 접두어를 붙인 함수를 제공하죠.
여러 기능의 함수가 많지만 우선 간단하게 4바이트 메모리에 락을 걸어 작동하는 함수들에 대해 정리를 해봤습니다. 

< 대입 >
LONG InterlockedExchange( LPLONG Target, LONG Value ); 

< 덧셈 value+=arg >
LONG InterlockedExchangeAdd( LPLONG Addend,LONG Increment); 

< 증가 value++ >
LONG InterlockedIncrement( LPLONG lpAddend ); 

<감소 value-- >
LONG InterlockedDecrement( LPLONG lpAddend ); 

< 비교후 바꾸기 if value==check then value=exchange >
LONG InterlockedCompareExchange(LPLONG Destination, LONG Exchange, LONG Comperand); 

사용예를 간단히 살펴보면 long 형 변수 lValue 가 있을때... 

하나 증가 
InterlockedIncrement(&lValue); 

하나 감소
InterlockedDecrement(&lValue); 

100과 같다면 0으로 바꿈 
InterlockedCompareExchange((VOID**)&lValue, (VOID*)0, (VOID*)100)

하나감소하는데.. 감소후 0이 됐을때 분기처리 
if (InterlockedCompareExchange((VOID**)&lValue, (VOID*)0, (VOID*)1)==(VOID*)1)
// 0 일때 처리
else
InterlockedDecrement(&lValue);

IOCP기반의 서버를 만들때 간단한 카운터처리를 해야할 부분이 많은데... 한 예로 WSASend()함수를 사용 해서 10명의 클라이언트에게 전송했다면, 메세지큐에서 10번의 전송완료 메세지가 나오게 되죠. 만약 단일 쓰레드로 작업을 처리한다면 모르지만 다중 쓰레드일 경우 이때 만약 처음 나온 메세지를 보고 Send의 버퍼를 해제나 풀에 돌려보내 버린다면 메모리 오류가 발생하거나 잘못된 데이터가 전송되게 됩니다. 그러서 완료횟수를 카운터해서 기억해야하는 작업이 필요한 거죠. 이런 간단한 수치를 바꾸는 일에 일일이 크리티컬섹션을 쓰기보다는 Interlocked계열의 함수를 쓰면 편리하겠죠? Interlocked는 또 CPU레벨에서 지원해주기 때문에 성능도 월등한점을 보입니다. 단 Interlocked의 경우 2003서버부터 지원 가능 할 것이고, ExInterlocked의 경우는 XP이상의 운영체제에서 지원 됩니다. 다음에 여유가 되면 Interlocked 링크드 쪽을 설명하겠음.

반응형