강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

Ulfric0531님의 프로필 이미지
Ulfric0531

작성한 질문수

Windows System 프로그래밍

01_Windows_OS_개요

Critical Section과 SRWlock의 차이

해결된 질문

작성

·

18

·

수정됨

0

Spin Count 초과 이후 스레드가 'Blocked' 상태에서 깨어나는 과정에서의 Critical Section과 SRWLOCK의 차이가 궁금합니다.

 

영천님의 LockTest 예제 코드를 이용하여 Lock을 선점한 스레드가 Lock을 해제하기 전에 Sleep() 코드를 추가한 상태에서 디버깅을 시작해보았습니다. (대기 중인 스레드의 Spin Count 초과 유도)

 

우선 두 경우 모두 락을 선점한 스레드가 락을 해제하면서 어떤 메모리 주소와 맵핑된 Thread ID를 읽어와서 내부적으로 NtAlertThreadByThreadId()의 인자로 넘겨주는것은 동일하였습니다.

 

하지만 Critical Section의 경우에는 LeaveCriticalSection() 내부에서 RtlpWakeByAddress()를 추가로 호출하고 대기중인 Thread ID를 얻어온 뒤 그 함수의 내부에서 NtAlertThreadByThreadId()를 호출하는 반면, SRWlock의 경우에는 ReleaseSRWLockExclusive() 내부에서 다른 함수 Call 없이 Critical Section보다는 보다 간소화(?)된 동작으로 Thread ID를 얻어오고 곧바로 NtAlertThreadByThreadId()를 호출하였습니다.

 

이걸보고 든 의문인데 영천님 블로그에 올라와있는 'Spin Count 도중 YieldProcessor() 관련 내용'을 제외하고 혹시 Critical Section과 SRWlock사이 성능 차이의 이유는 애초에 SRWlock은 Spin Count를 초과한 상태일때 ReleaseSRWLockExclusive()을 호출한 스레드에서 보다 간소화된 동작과 불필요한 함수 Call 없이 Thread ID를 얻어올 수 있도록 어떠한 정보(?)를 추가해준 뒤 Blocked 상태에 빠지게되는 등의 기능 때문이라고 봐도 될까요? 아직 근거 없는 추측이긴 합니다...

답변 2

1

megayuchi님의 프로필 이미지
megayuchi
지식공유자

ai가 답변한것 이상으로 제가 답변할게 있을까 모르겠네요. 저도 자세히 살펴보진 않았거든요. 다만 SRWLOCK이 조금이라도 더 간소화될 수 있는 이유중 하나는 재진입을 허용하지 않기 때문이라 생각합니다.

CriticalSection은 이미지 진입한 스레드가 재진입하는걸 허용하고 있고 이를 위한 카운터변수와 스레드 핸들을 들고 있죠. srwlock은 소유자 스레드에 대해 구분하지 않습니다.

이것이 간소화된 호출경로를 가질 수 있는 이유라고 생각합니다. 그리고 재진입이 불가할 경우, 그러니까 CriticalSection을 SRWLock으로 대체하면 큰일나는 프로젝트도 있거든요. CriticalSection을 완전히 SRWLock으로 대체할 수 없는 이유이기도 하구요.

Ulfric0531님의 프로필 이미지
Ulfric0531
질문자

아 CriticalSection의 멤버 변수인 RecursionCount가 재진입 횟수에 해당되는 부분이겠네요.

 

확실히 구현하려는 로직에 따라 같은 스레드에서 동일한 Lock 객체에 대한 재진입의 필요성이 존재하는 코드들도 있을터라 성능과 별개로 CriticalSection을 사용해야하는 부분이 분명히 존재하겠군요.

 

잘 이해가 됐습니다 항상 감사드립니다.

0

안녕하세요, 인프런 AI 인턴입니다. Ulfric0531님.

Critical Section과 SRWLock의 차이를 이해하는 것은 멀티 스레드 프로그래밍에서 성능 최적화에 중요한 역할을 합니다. 질문해 주신 두 가지 동기화 도구의 차이점을 간단히 설명드리겠습니다.

Critical Section과 SRWLock의 차이

  1. Critical Section:

    • Critical Section은 스레드들의 액세스를 직렬화하는 데 사용되며, 같은 프로세스 내에서만 사용할 수 있습니다.
    • Critical Section은 Spin Count를 지원하여 짧은 시간 동안 바쁜 대기를 하다가 스핀을 포기하고 OS에 컨트롤을 넘깁니다.
    • LeaveCriticalSection()RtlpWakeByAddress()를 호출하여 블록된 스레드를 깨우는데, 이는 비교적 복잡한 과정으로 성능에 약간의 영향을 줄 수 있습니다.
  2. SRWLock (Slim Reader/Writer Lock):

    • SRWLock은 더 가볍고, 특히 읽기-쓰기 잠금이 필요한 상황에서 효율적입니다.
    • SRWLock은 Spin Count 초과 후 최소한의 오버헤드로 스레드를 깨웁니다. ReleaseSRWLockExclusive()가 직접 NtAlertThreadByThreadId()를 호출하여 더 적은 함수 호출을 통해 블록된 스레드를 깨어나게 합니다.
    • SRWLock은 더 현대적인 디자인으로, 상황에 따라 비교적 빠른 성능을 제공합니다.

성능 차이의 원인

  • 함수 호출 최적화: SRWLock이 Critical Section보다 간단한 호출 체인을 가지고 있기 때문에 특정 상황에서 성능상의 이점을 가질 수 있습니다.
  • 최소 오버헤드 구조: SRWLock은 OS 레벨에서 더 낮은 API를 통해 스레드 상태를 관리하여, 불필요한 함수 호출을 줄입니다.

결론

SRWLock은 특정 시나리오에서 성능 면에서 유리할 수 있으며, 특히 많은 스레드가 동시에 읽기 액세스가 필요한 경우 더 효율적입니다. 하지만, 둘 중 어느 한 쪽이 항상 더 좋다고 단정할 수는 없으며, 사용 사례에 따라 선택하는 것이 중요합니다.

관련 질문에 대한 보다 깊은 이해를 위해 몇 가지 참고 자료를 소개합니다:
- SRWLock과 Critical Section 비교 - 두 동기화 메커니즘의 심층적인 성능 비교를 제공합니다.
- 동기화 메커니즘 최적화 - 성능 최적화를 위한 다양한 동기화 기법을 다루고 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

Ulfric0531님의 프로필 이미지
Ulfric0531

작성한 질문수

질문하기