Slim Reader Writer Lock은 VS2010부터 지원되는 새로운 쓰레드 동기화 객체입니다.

특징

  • 기존 CriticalSection 비해 조금 더 적은 메모리 사용과 빠른 수행 속도를 가집니다.

  • Reader 쓰레드와 Writer 쓰레드가 완전히 분리될 수 있을 경우 사용될 수 있습니다.

적은 메모리 사용

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
 
    //
    //  The following three fields control entering and exiting the critical
    //  section for the resource
    //
 
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;        // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;        // force size on 64-bit systems when packed
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
 
typedef struct _RTL_SRWLOCK {                            
        PVOID Ptr;                                      
} RTL_SRWLOCK, *PRTL_SRWLOCK;
  • SRWLock은 하나의 포인터로 구성되어 있습니다. 이로 인해, 메모리의 크기와 업데이트 해야 할 정보의 크기가 CriticalSection에 비해 상당히 작습니다.

단점

  • Recursively lock을 사용할 수가 없다.

    CriticalSection의 경우 이미 진입한 쓰레드의 경우 중첩 lock 진입이 가능했지만,

    SWRLock의 경우 이미 진입한 쓰레드라 할 지라도 다시 한번 진입 시도시 락이 해제되지 않기에, 사용에 주의가 필요합니다.

    동일 쓰레드에서 이미 중첩 진입이 되면, 이후 락 해제 코드를 여러 번 넣어둬도 아무런 소용이 없습니다.

  • Owning thread를 알 수 없다.

    A 쓰레드에서 SRWLock을 걸고, B 쓰레드에서 이를 풀 수 있다.

Shared/Exclusive mode

  1. Reader 쓰레드와 Writer 쓰레드가 분리되어 있는 경우 아래와 같이 두 가지 모드로 SRW 락을 사용할 수 있습니다.

    Shared mode : 복수의 쓰레드가 read-only로 접근시 훨씬 더 강력한 성능 발휘

    Exclusive mode : 복수의 쓰레드가 읽고 쓸 때 사용하는 모드

  2. 두 가지 모드 관련해서 사용상 주의점

    Shared mode로 락을 획득한 쓰레드는 Exclusive mode로 이 락을 사용해서는 안 된다는 점입니다.

사용

//먼저, SRWLOCK 구조체를 초기화 시켜줘야 합니다.

void InitializeSRWLock(PSRWLOCK SRWLock);

//이후 락 진입시/해제시엔 다음 함수들를 사용하면 됩니다.

//진입

void AcquireSRWLockExclusive(PSRWLOCK SRWLock);
void AcquireSRWLockShared(PSRWLOCK SRWLock);

//해제 

void ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
void ReleaseSRWLockShared(PSRWLOCK SRWLock);

//CritialcalSection의 Try~ 함수도 존재합니다.

bool TryAcquireSRWLockExclusive(PSRWLOCK SRWLock);
bool TryAcquireSRWLockShared(PSRWLOCK SRWLock);

CriticalSection은 DeleteCriticalSection이라는 종료 함수가 존재했지만, SRWLock은 별도의 종료 함수는 존재하지 않습니다.