※ 커널 오브젝트가 생성될 때는 non-signaled 상태에 있다가 종료하는 경우에 signaled상태로 바뀐다.
※ nonsignaled상태이면 WaitForSingleObject가 멈추고 그렇지 않으면 통과(리턴)할 수 있다.
19-1. 쓰레드 동기화 기법의 분류
프로세스 실행의 두 가지 모드
사용자 모드(User Mode)와 커널 모드(Kernel Mode)
user mode : 시스템 리소스를 제외하고 원하는대로 사용가능.
접근할 수 있는 메모리 공간이 제한되어 있음.
물리적 영역으로 직접 접근이 허용되지 않는다.
사용자 모드 동기화 기법 : CRITICAL_SECTION 오브젝트 사용
장점 : 프로그래밍하기 수월, 속도가 빠르다.
단점 : 커널 모드 동기화 기법에 비해 제한된 기능만 가진다.
kernel mode : 시스템 리소스를 접근할 수 있지만 시스템 콜을 통해서만 운영체제에서 직접 처리한다
시스템의 모든 메모리 영역으로 접근 가능.
시스템 리소스 : 파일, 쓰레드
시스템의 안전성을 보장하기 위해서 제공
커널 모드 동기화 기법 : Event, Semaphore, Mutex (다른 프로세스에서 접근 가능)
장점 : Deadlock 문제를 막을 수 있다. 둘 이상의 프로세스 내에 존재하는 쓰레드 간의 동기화 가능.
단점 : 실행 속도의 저하가 발생.
19-2. CRITICAL_SECTION
동기화 관련 함수
※ lpCriticalSection : CRITICAL_SECTION 변수의 포인터
CS 초기화 : void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
CS 소유(임계영역에 들어갈 때) : void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
CS 반환(임계영역을 나올 때) : void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
CS 소멸 : void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
커널 오브젝트의 상태
뮤텍스
signaled 상태 -> 뮤텍스 소유가 가능한 상태
non-signaled 상태 -> 뮤텍스가 이미 가지고 있는(소유되어진) 상태
세마포어
signaled 상태 -> 세마포어 카운트가 0이 아닌 경우.
non-signaled 상태 -> 세마포어 카운트가 0인 경우.
BOOL CloseHandle(HANDLE hObject);
커널 오브젝트 객체를 소멸한다. 참조카운트 1 감소.
19-3. Mutex(Mutual Exclusion)
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes,
BOOL bInitialOwner,
LPCTSTR lpName
);
뮤텍스 객체를 생성하고 참조카운트 1 증가.
리턴 : 성공시 생성된 Mutex 오브젝트 핸들, 실패시
lpMutexAttributes : 보안설정
bInitialOwner : false는 signal, true는 non-signal상태로
lpName : 객체 이름
※ WaitSingleObject함수는 뮤텍스를 가져오는(lock) 함수
BOOL ReleaseMutex(
HANDLE hMutex
);
Mutex를 돌려주는(unlock)하는 함수.
리턴 : 성공시 TRUE 실패시 FALSE
non-signaled -> signaled
Mutex를 통한 쓰레드 동기화
19-4. Semaphore
세마포어가 0이 되어야 세마포어 오브젝트 non-signaled 상태가 된다.
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBTE lpSemaphoreAttributes,
LONG lInitialCount,
LONG lMaximumCount,
LPCTSTR lpName
);
세마포어 객체를 생성하고 참조카운트 1 증가.
리턴 : 성공시 생성된 Mutex 오브젝트 핸들, 실패시
lpMutexAttributes : 보안설정
lInitialCount : 초기 세마포어값.
lMaximumCount : 세마포어의 최대값.
lpName : 객체 이름
※ WaitForSingleObject는 세마포어 값을 감소시킨다. signaled상태 -> nonsignaled상태로
BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);
리턴 : 성공시 TRUE, 실패시 FALSE
hSemaphore : 세마포어의 핸들.
lReleaseCount : 세마포어 값을 증가시킬 크기
lpPreviousCount : 이 함수를 호출하기 전에 카운트 값을 저장할 수 있다.
19-5. Event
Event 특징 : auto & manual-reset 모드의 커널 오브젝트의 생성이 가능하다.
※ 대기 중에 있는 쓰레드들을 한꺼번에 깨울 수 있다. (장점)
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName
);
이벤트를 생성한다.
리턴 : 성공시 생성된 Event 오브젝트 핸들. 실패시 NULL
lpEventAttributes : 보안설정
bManualReset : TRUE면 manual-reset 모드의 이벤트 생성.
bInitialState : TRUE면 signaled 상태의 이벤트 생성, FALSE면 non-signaled 상태의 Evenet가 생성
lpName : Event에 이름을 준다.
manual-reset 모드 Event 동기화 원리
1. hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); -> 쓰레드 생성하면 대기상태로 생성.
2. SetEvent(hEvent);
3. NumberOfA, NumberOfOthers가 수행됨.
'네트워크 프로그래밍' 카테고리의 다른 글
[TCP/IP 소켓 프로그래밍] 21. Overlapped 입출력 모델 (0) | 2009.09.11 |
---|---|
[TCP/IP 소켓 프로그래밍] 20. 동기와 비동기의 이해 (2) | 2009.08.28 |
[TCP/IP 소켓 프로그래밍] 18. 윈도우즈 기반 쓰레드 사용하기 (0) | 2009.08.20 |
[TCP/IP 소켓 프로그래밍] 17. 프로세스(Process)와 쓰레드(Thread) (0) | 2009.08.19 |
[TCP/IP 소켓 프로그래밍] 16. 입력과 출력 스트림의 완벽 분리 (0) | 2009.08.17 |