크리티컬 섹션 - 유저레벨 어플리케이션 작성시 가장 간단하게 사용
- 유저레벨 동기화 방법 중 유일하게 커널 객체를 쓰지 않음
- 커널 객체를 쓰지 않기 때문에 핸들을 쓰지 않고 CRITICAL_SECTION 이라는 타입을 정의해서 사용
뮤텍스 - 뮤텍스는 최초에 Signal 상태로 생성되어짐.
WaitForSingleObject()와 같은 대기 함수를 호출함으로 NonSignaled 상태가 됨
대기 함수에 대한 최초의 접근은 그 상태가 Signaled 이므로 스레드가 대기없이 해당 영역으로 진입함
진입 이후엔 NonSignaled 상태가 되므로 그 이후에 접근하는 스레드들은 대기하게 됨
최후에 뮤텍스는 ReleaseMutex() 함수를 사용함으로 Signaled 상태로 돌아옴. 다른 스레드들이 접근 가능해짐
- 뮤텍스는 스레드가 여러 개 있더라도 자신이 소유한 스레드가 누군지 기억하고 있음.
Windows 운영체제는 뮤텍스가 반환되지 않고 스레드가 종료가 되면 그 뮤텍스를 강제적으로 Signaled 상태로 돌려놓음
- 뮤텍스는 소유한 스레드를 기억함으로 같은 스레드가 같은 뮤텍스를 중복 호출하더라도 데드락이 발생하지 않게 함
내부적으로 카운터만 증가시키며 기억된 스레드에 대한 진입은 허용함
내부적 카운터가 0이 되었을 때 Signaled 상태로 돌려줌으로 중복 호출한 스레드가 사용을 완전히 종료 했을 때 다른 스레드가 진입
가능. 이로 인해 재귀 호출에 의한 데드락을 방지
이벤트 - 어떤 사건에 대해 알리기 위한 용도로 사용되는 동기화 객체
windows에서 메시지를 교환 하는 것과 개념이 같음. 즉 windows의 메시지 교환 방식은 이벤트에 기인함.
키보드가 눌러질 경우 WM_KEYDOWN 메시지가 날아오며 이 신호를 이벤트를 통해 통보함
- 이벤트의 경우 SetEvent() 또는 ResetEvent()를 사용하여 동기화 객체들의 상태를 마음대로 변경 가능
세마포어 - 사용자가 지정한 개수만큼 세마포어 동기화 객체로 보호하는 자원에 대해 접근 할 수 있도록 함
사용 가능한 자원의 개수를 세팅하게 되어 있으며 이는 초기화에서 이뤄짐
- 세마포어가 초기화 되었을 때에는 뮤텍스와 마찬가지로 Signaled 상태로 됨
세마포어의 자원이 하나 사용 될 때마다 사용 가능한 자원의 개수는 하나 씩 감소하게 됨
자원의 개수가 1 이상일 때에는 Signaled 상태로 유지되고 이 값이 0이되면 NonSignaled 상태가 됨
자원의 개수가 다시 1 이상이 되면 Signaled 상태로 돌아옴
- 세마포어의 자원에 대한 반환은 ReleaseSemaphore()를 사용