'Mutex'에 해당되는 글 2건

  1. 2011.12.01 [Mutex]
  2. 2011.11.30 [Mutex Thread 동기화 예제]

[Mutex]

Development/C/C++ 2011. 12. 1. 20:04

Mutex (Mutual Exclusion)

CRITICAL_SECTIOn 오브젝트 이용한 방법과 상당히 유사하다. 따라서 Mutex 또한 열쇠라고 생각하고 이해하기 바란다.

 

Mutex 오브젝트 함수
1. Mutex 오브젝트를 생성하는 함수 
HANDLE CreateMutex ( 

LPSECURITY_ATTRIBUTES    lpMutexAttributes,      // 생성된 핸들을 자식 프로세스가 상속 받도록 할 것인가에 대한 설정

BOOL      bInitialOwner,  // TRUE 전달시, 생성된 Mutex의 소유자가 함수를 호출한 쓰레드로 초기화

                                    // FALSE 전달시, Mutex의 소유자가 존재하지 않음

LPCTSTR lpName      // 생성되는 Mutex에 이름을 줄 경우 사용되는 인자 
) ; 

2. 임계 영역에 들어가기 위해 Mutex를 얻는 함수

WaitForSingleObject 함수가 Mutex를 소유하는 역할을 한다.

(이 함수는 커널 오브젝트가 non-signaled 상태에서 signaled 상태가 되기를 기다리는 함수이다.

  타임 아웃을 설정하여 무한 대기 상태에 빠지는 것을 막을 수도 있다.)
 

3. 임계 영역을 나갈 때 Mutex를 반환하는 함수

BOOL ReleaseMutex ( HANDLE hMutex ) ;        // 반환하고자 하는 Mutex를 인자로 전달

 
4. Mutex를 소멸하는 함수

BOOL CloseHandle ( HANDLE  hObject ) ;         // 소멸하고자 하는 커널 오브젝트의 핸들을 전달

Mutex 오브젝트 소유자가 존재하는 경우 non-signaled 상태, 소유자가 존재하지 않는 경우 signal 상태가 된다.

 

 
 

'Development > C/C++' 카테고리의 다른 글

[Event]  (0) 2011.12.01
[Semaphore]  (0) 2011.12.01
[CriticalSection]의 사용  (0) 2011.12.01
[시스템 함수 정리]  (0) 2011.11.30
[Mutex Thread 동기화 예제]  (0) 2011.11.30
Posted by cyj4369
,

// Kernel object Mutex Thread 동기화 예제
// 1.signaled == 소유가 가능한 상태:
// WaitForSingleObjet 함수를 호출하여 전달된 mutex Handle인자를
// non-signaled 상태로 변경하여 이미 소유되어진 상태로 만든다. (소유 잠금 함수)
// non-signaled == 이미 소유되어진 상태:
// ReleaseMutex 함수를 호출하여 전달된 mutex Handle인자를
// singnaled 상태로 변경하여 소유가능 상태로 만든다. (소유 해제 함수)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>

DWORD WINAPI ThreadIncrement(void *arg);
void ErrorHandling(char *message);

char thread1[] = "A Thread";
char thread2[] = "B Thread";

// 임계영역에 해당되는 전역변수 선언
// 다중 thread함수에 의해 값이 변경되는 변수
int number = 0;
// 핸들 자료형으로 mutex핸들로 사용할 변수 선언
HANDLE hMutex;

int main(int argc, char *argv[])
{
HANDLE hThread[2]; // 핸들 자료형으로 thread핸들로 사용할 변수 선언
DWORD dwThreadID[2]; // 생성되는 thread의 ID로 사용할 변수 선언

// mutex를 생성
// (보안관련 설정: NULL, 소유여부 설정: FALSE(==signaled) , Mutex이름: NULL)
// 소유가 가능한 상태로 mutex 를 생성
hMutex = CreateMutex(NULL, FALSE, NULL);

// mutex 생성 실패시 처리
if(hMutex==NULL)
ErrorHandling("CreateMutex() Error");

// thread에 안전한 함수 호출 방식으로 thread함수 호출함과 인자를 넘겨 주면서 thread ID생성
hThread[0] = (HANDLE) _beginthreadex(NULL, 0, ThreadIncrement, (void*)thread1, 0, &dwThreadID[0]);
hThread[1] = (HANDLE) _beginthreadex(NULL, 0, ThreadIncrement, (void*)thread2, 0, &dwThreadID[1]);

// thread 생성 실패시 처리
if(hThread[0] == 0 || hThread[1] == 0)
ErrorHandling("_beginthreadex() Error");

// thread함수 처리 종료 까지 대기한다.
if(WaitForMultipleObjects(2, hThread, TRUE, INFINITE) == WAIT_FAILED)
ErrorHandling("WaitForMultipleObjects() Error");

// thread함수에 의해 변경된 임계영역에 해당하는 number 값을 출력
printf("main() function end, last number : %d \n", number);

// 생성되었던 mutex핸들을 소멸 시킨다.
// CloseHandle함수는 어떠한 handle이라도 소멸 시킬수 있다.
// 여기서는 mutex 핸들을 소멸 시키는 것을 보여주고 있다
CloseHandle(hMutex);

return 0;
}

DWORD WINAPI ThreadIncrement( void *arg )
{
int i;

for(i=0; i<5; i++){
// mutex를 non-signaled 상태로 변경(소유를 한다음 소유 불가능 상태로 잠금)
WaitForSingleObject(hMutex, INFINITE);
Sleep(100); // 실행결과를 눈으로 확인 하기 위해 사용 ^^
number++;
printf("Run : %s, number : %d \n", (char*)arg, number);
// mutex를 signaled 상태로 변경(소유를 포기한다음 소유가능 상태로 해제함)
// 참고로 참조하는 부분도 mutex로 묶어준 이유는 참조하는 순간 다른 thread함수에 의해
// 값이 변경되는 것을 막기 위함이다.
ReleaseMutex(hMutex);
}

return 0;
}

void ErrorHandling( char *message )
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}

Posted by cyj4369
,