컴퓨터 공부/Win32 API 프로그래밍

[5월 11일 2교시] 동기화 1

려리군 2009. 5. 11. 16:09

경쟁 상태 : 멀티 쓰레드에 의해 시간이나 순서가 의도하지 않게 혹은 치명적으로 결과가 나오는 경우.

-> 동기화로 문제 해결.


Critical Section(크리티컬 섹션)

공유 자원의 독점을 보장하는 코드의 한 영역.

한 프로세스 내에서만 사용 가능하다.

공유자원을 얻기 위해 대기할 때 CPU시간을 포기한다.


void WINAPI InitializeCriticalSection(__out  LPCRITICAL_SECTION lpCriticalSection);

참고주소 : http://msdn.microsoft.com/en-us/library/ms683472(VS.85).aspx

크리티컬 섹션을 초기화 한다.

lpCriticalSection : 크리티컬 섹션 객체 포인터. 프로그램에서 전역변수로 선언해야 한다.


void WINAPI DeleteCriticalSection(__inout  LPCRITICAL_SECTION lpCriticalSection);

참고주소 : http://msdn.microsoft.com/en-us/library/ms682552(VS.85).aspx

크리티컬 섹션에서 사용된 모든 자원을 해제한다.

lpCriticalSection : 크리티컬 섹션 객체 포인터. 객체는 반드시 초기화되어 있어야 한다.


void WINAPI EnterCriticalSection(__inout  LPCRITICAL_SECTION lpCriticalSection);

참고주소 : http://msdn.microsoft.com/en-us/library/ms682608(VS.85).aspx

특정 크리티컬 섹션 객체의 소유권을 기다린다. 함수는 소유권을 쓰레드로부터 얻었을 때 리턴한다.

lpCriticalSection : 크리티컬 섹션 객체 포인터.


void WINAPI LeaveCriticalSection(__inout  LPCRITICAL_SECTION lpCriticalSection);

참고주소 : http://msdn.microsoft.com/en-us/library/ms684169(VS.85).aspx

특정 크리티컬 섹션 객체 소유권을 반납한다.

lpCriticalSection : 크리티컬 섹션 객체 포인터.


교착상태(Deadlock) : 모든 쓰레드의 대기 상태가 종료되지 않아 무한정 대기만 하는 상태


동기화 객체

커널 객체, 프로세스 한정적인 핸들을 가진다.

신호상태 : 쓰레드의 실행을 허가. 신호등의 파란불에 비유할 수 있다.

비신호상태 : 쓰레드는 block된다. 신호등의 빨간불에 비유할 수 있다.


대기함수

DWORD WINAPI WaitForSingleObject(__in  HANDLE hHandle, __in  DWORD dwMilliseconds);

참고주소 : http://msdn.microsoft.com/en-us/library/ms687032.aspx

특정 객체가 신호 상태나 timeout시간이 지나갈 때까지 기다린다.

hHandle : 객체의 핸들. 기다리는 상태에서 핸들이 닫히면 함수의 행동은 어떻게  될 지 모른다.(undefined)

핸들은 SYNCHRONIZE 접근 권한을 가져야 한다.

dwMilliseconds : 밀리초 단위의 timeout 간격. 

리턴 : 함수의 이벤트(상황) 

 - WAIT_ABANDONED : 포기된 뮤텍스. 

뮤텍스는 자신을 쓰레드가 누구인지 기억하고 있다. 소유 쓰레드가 뮤텍스를 해제하지 않고 뮤텍스를 강제로 신호상태로 만들어 준다.

 - WAIT_OBJECT_0 : 객체의 상태가 신호상태가 됨.

 - WAIT_TIMEOUT : timeout 간격이 지났고 객체의 상태는 비신호상태이다.

 - WAIT_FAILED : 실패

DWORD WINAPI WaitForMultipleObjects(__in  DWORD nCount, __in  const HANDLE *lpHandles,  __in  BOOL bWaitAll, __in  DWORD dwMilliseconds);
특정 객체 중 하나 혹은 모두가 신호 상태이거나 timeout 시간이 지나갈 때까지 기다린다.
리턴 : 함수의 상황
nCount : 객체 핸들의 개수
lpHandles : 객체 핸들의 배열 포인터
bWaitAll : TRUE면 모든 객체 상태 배열을 신호상태로 만들고 FALSE면 여러 객체 중 하나를 신호상태로 만든다. 
dwMilliseconds : 밀리초 단위의 timeout 간격. 

뮤텍스 : 한 개의 공유자원을 보호 할 때 사용.
상호배제. Mutual Exclusion
프로세스 간에도 사용 가능.
두 쓰레드가 동시에 소유할 수 없다

한 쓰레드가 자원을 가지면 비신호상태가 된다.


CreateMutex(보안속성, 소유여부, 뮤텍스 이름)

HANDLE WINAPI CreateMutex(__in_opt  LPSECURITY_ATTRIBUTES lpMutexAttributes, __in      BOOL bInitialOwner, __in_opt  LPCTSTR lpName);

참고주소 : http://msdn.microsoft.com/en-us/library/ms682411.aspx

이름이 있거나 없는 뮤텍스 객체를 생성하고 연다. 객체에 대한 접근 마스크를 정의하고 싶으면 CreateMutexEx함수를 사용한다.

리턴 : 성공시 새롭게 생성된 뮤텍스 객체의 핸들. 실패시 NULL.

lpMutexAttributes : SECURITY_ATTRIBUTES 구조체의 포인터. NULL이면 자식 프로세스로 상속되지 않는 핸들을 만든다.

bInitialOwner : TRUE면 호출자가 뮤텍스를 만들며 쓰레드는 뮤텍스 객체의 초기 소유권을 얻는다.

lpName : 뮤텍스 객체의 이름. 이름은 MAX_PATH만큼으로 제한된다. 이름 비교는 대소문자를 구분한다.

오류값 

 - ERROR_ALREADY_EXISTS : 이미 이름이 존재하는 쓰레드.

 - ERROR_ACCESS_DENIED : 호출자가 접근 권한이 없을 경우. OpenMutex를 사용하여야 한다.


BOOL WINAPI ReleaseMutex(__in  HANDLE hMutex);

참고주소 : http://msdn.microsoft.com/en-us/library/ms685066.aspx

특정 뮤텍스 객체에 대한 소유권을 반납한다. 뮤텍스를 신호상태로 만든다.

리턴 : 성공시 TRUE 실패시 FALSE

hMutex : CreateMutex나 OpenMutex에 의해 리턴된 뮤텍스 객체 핸들.


세마포어 : 제한된 일정 개수의 자원을 보호.

예시 : 동시에 3개까지만 다운로드 가능하게 할 때.


HANDLE WINAPI CreateSemaphore(__in_opt  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, __in      LONG lInitialCount, __in      LONG lMaximumCount, __in_opt  LPCTSTR lpName);
이름이 있거나 없는 세마포어 객체를 생성하거나 연다.
리턴 : 성공시 세마포어 객체 핸들. 실패시 NULL
lpSemaphoreAttributes : SECURITY_ATTRIBUTES 구조체의 포인터. NULL이면 자식 프로세스로 상속되지 않는 핸들을 만든다.
lInitialCount : 세마포어 객체의 초기화 값. 0이상 lMaxinumCount이하여야 한다. 
lMaxinumCount : 세마포어 객체를 위한 최대값. 0보다 커야 한다.
lpName : 뮤텍스 객체의 이름. 이름은 MAX_PATH만큼으로 제한된다. 이름 비교는 대소문자를 구분한다.

오류값 

 - ERROR_ALREADY_EXISTS : 이미 이름이 존재하는 쓰레드.


BOOL WINAPI ReleaseSemaphore(__in       HANDLE hSemaphore, __in       LONG lReleaseCount, __out_opt  LPLONG lpPreviousCount);

참고주소 : http://msdn.microsoft.com/en-us/library/ms685071.aspx

정한 수만큼 세마포어 객체의 값을 증가시킨다.

리턴 : 성공시 TRUE, 실패시 FALSE

hSemaphore : 세마포어 객체의 핸들. CreateSemaphore나 OpenSemaphore함수가 이 핸들을 리턴한다.

핸들은 SEMAPHORE_MODIFY_STATE 권한을 가져야 한다.

lReleaseCount : 세마포어 객체의 카운트 값을 증가시킬 양. 이 값은 0보다 커야 한다.

lpPreviousCount : 세마포어의 이전 카운트 값을 얻는 변수 포인터.