본문 바로가기

Hello CE,Mobile

CreateMutex()



쓰레드(Thread)는 멀티프로세스가 지원되는 OS에서 실행의 최소 단위입니다..

 

쓰레드가 모여서 하나의 프로세스를 구성하지요... 그러니까 프로세스를 기동시키면

 

한개 이상의 쓰레드가 기동되는것을 의미하는것죠....

 

하나의 프로세스에 여러개의 쓰레드를 기동시키기도 합니다..

 

프로세스는 말 그데로.. 독립적인 실행의 단위입니다...

 

대충 프로세스와 쓰레드는 설명이 되었고..

 

Visual C++을 사용하면 동기화에 관련된 몇가지 모듈을 제공합니다..

 

크리티컬섹션(CriticalSection)

뮤텍스(Mutex)

세마포어(Semaphore)

 

그 밖에 기타 Event, Overlapped 등을 지원합니다...

 

동기화(상호배제)에 관해서는 님께서 대충 아신다고 하니.. 그 부분은 설명하지 않고..

 

크리티컬섹션과 뮤텍스의 차이점과 CreateMutex()에 관해서만 설명드리겠습니다..

 

크리티컬섹션이나 뮤텍스는 어떻게 보면 기능상 똑같다고 생각하시면 됩니다. 약간은 차이는 나지만..

 

근본적인 차이는 크리티컬섹션은 하나의 프로세스 안에서만 동작하는 것이고

(그러니까 하나의 프로세스안에 여러개의 쓰레드가 있을경우 그 쓰레드들간의 상호배제를 구현하는것이지요)

 

뮤텍스는 문자열로 뮤텍스의 이름을 지정해 주면 뮤텍스의 이름으로 프로세스간에도 상호배제를 사용할 수 있습니다..

 

윈도우즈의 뮤텍스와 관련된 함수는 다음과 것들이 있습니다.
 
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName);
HANDLE OpenMutex(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName);
BOOL ReleaseMutex(HANDLE hMutex);
 

CreateMutex()함수는 뮤텍스를 생성합니다.
이미 생성된 이름을 갖는 뮤텍스의 핸들을 얻기 위해서는 OpenMutex()를 사용합니다.
뮤텍스의 사용이 끝나서 해당 뮤텍스를 놓아 줄때는 ReleaseMutex()함수를 사용합니다.
위에 원형은 밝히지 않았지만 생성한 뮤텍스를 파괴시킬때는 모든 커널객체가 그렇듯 CloseHandle()함수를 사용합니다.
참고로 신호상태인 뮤택스를 얻기 위해서는 위에서 설명한 대기함수를 사용해야 한다는 것은 짐작하셨겠죠?
 
이때 CreateMutex()는 이미 다른 프로세스에서 사용하고자 하는 뮤텍스를 생성하였다면 CreateMutex()함수를 호출하지 않고 OpenMutex()를 사용해도 되지만 CreateMutex()함수를 다시 한번 더 호출해도 상관이 없습니다.
 
CreateMutex()함수의 아큐먼트는 다음과 같습니다.
- lpMutexAttributes : 뮤텍스의 보안 속성을 지정하는 것으로서 주로 상속관계를 지정하기 위해 사용됩니다. 일반적으로는 NULL을 입력합니다.
- bInitialOwner : 뮤텍스를 생성하면서 사용권한을 갖을 것인지를 결정합니다. 즉, TRUE를 입력하면 생성하자 마자 뮤텍스의 사용권한(비신호상태의 뮤텍스 생성)을 갖습니다. FALSE를 입력할 경우 뮤텍스만 생성하기만(신호상태의 뮤텍스 생성) 하고 실제 사용권한을 얻을때는 대기함수를 사용해야 합니다.
- lpName : 뮤텍스에 이름을 문자열로 지어 줍니다. 이름이 지정된 뮤텍스를 만듦으로서 이 이름을 아는 다른 프로세스와의 동기화를 할 수 있습니다. 하나의 프로세스에서만 동기화 방식으로 뮤텍스를 사용한다면 NULL을 입력하여 이름을 지어 주지 않을 수도 있습니다. 참고 이름을 지어준 뮤텍스를 명명된 뮤텍스(named mutex)라고 합니다.
 
CreateMutex()함수는 생성한 뮤텍스의 핸들을 리턴합니다. 만약 생성하려는 뮤텍스의 이름으로 이미 뮤텍스가 생성되어 있는 경우는 해당 뮤텍스 핸들을 리턴하고 GetLastError()로는 ERROR_ALREADY_EXISTS값을 얻을 수 있습니다. 만약 생성되어 있는 뮤텍스에 접근할 수 있는 권한이 없는 경우(ERROR_ACCESS_DENIED) NULL을 리턴합니다. 구체적인 원인을 알기 위해서는 GetLastError()함수를 호출하여 알 수 있습니다. 만약 EROR_ACCESS_DENIED일 경우는 OpenMutex()함수를 사용하여야 합니다.
 
OpenMutex()함수의 아큐먼트는 다음과 같습니다.
- dwDesiredAccess : 접근속성
- bInheritHandle : 상속옵션
- lpName : 지정된 뮤텍스의 이름
 
OpenMutex()함수는 이름이 지정된 뮤텍스의 핸들의 핸들을 리턴합니다. 만약 지정된 이름의 뮤텍스가 없는 경우는 NULL을 리턴하고 GetLastEror()함수는 ERROR_FILE_NOT_FOUND값을 리턴합니다.
 
일반적으로 OpenMutex()함수는 잘 사용하지 않습니다. 왜냐하면 CreateMutex()함수로 새로운 뮤텍스를 생성할 수도 이미 생성된 뮤텍스의 핸들을 얻을 수도 있기 때문이죠.
위에서 이야기 한대로 뮤텍스에 보안 속성을 설정한 경우 OpenMutex()를 사용하기도 합니다.
 
ReleaseMutex()함수는 잡았던 뮤텍스(비신호상태의 뮤텍스)를 다시 놓아주는(신호상태로 만들어 주는) 함수입니다.
아큐먼트는 hMutex에 뮤텍스 핸들을 넣어 줍니다. 놓아주기에 성공하면 TRUE를 실패하면 FALSE를 리턴합니다.

 

뮤텍스 설명에 관한 출처...

http://blog.naver.com/herryjoa?Redirect=Log&logNo=110028833001

-----------------------------------------------------------------------------------------------------------------------

2 크리티컬섹션 (Critical section) #

유저모드 동기화 객체
커널모드 객체가 아니기 때문에 가볍고 같은 프로세스내에 스레드 동기화에 사용할 수 있다.
EnterCriticalSection을 호출하면 객체는 비신호 상태가 되고,
LeaveCriticalSection을 호출하면 신호상태로 바뀌어서 다른 스레드들이 접근가능하다.

3 뮤텍스 (Mutex) #

커널모드 동기화 객체
커널모드라서 크리티컬 섹션보다는 느리지만 프로세스를 넘어서 모든 스레드에 사용 될 수 있는 동기화 객체이다.
뮤텍스를 신호상태로 생성한 후 스레드에서 Wait 함수를 호출하면 뮤텍스는 비신호 상태가 되어서 다른 스레드에서는 접근하지 못한다.
ReleaseMutex를 호출하면 뮤텍스는 신호상태가 되어 다른 스레드들이 접근가능하다.

4 세마포어 (Semaphore) #

커널모드 동기화 객체
뮤텍스와 비슷하지만 접근할 수 있는 스레드 갯수를 정할 수 있다.
세마포어를 생성할 때 3개의 스레드들이 접근가능하도록 지정하면 내부카운트값은 3이다.
객체 내부적으로 카운트를 관리하여 세마포어 객체를 Wait하는 스레드가 있으면 카운트가 하나씩 감소한다. 그래서 내부카운트가 0이되면 비신호상태로 바뀐다. [[br] 세마포어를 사용하고 있는 스레드들중 ReleaseSemaphore 하면 세마포어 내부카운트는 다시 1 증가하여 신호상태로 바뀌어서 다른 스레드들이 사용가능하게 된다.

※ 세마포어 생성 시 접근 가능한 스레드를 0으로 설정해서 WaitforSingleObject와 같은 효과를 내어서 사용하기도 하죠.


'Hello CE,Mobile' 카테고리의 다른 글

CreateEvent()  (0) 2009.12.03
윈도우 동기화  (0) 2009.12.02
eVC4 에서 link시 CVT1102 에러  (0) 2009.11.25
인터럽트 처리과정  (0) 2009.11.17
IRQ(Interrupt Request) 란  (0) 2009.11.17