티스토리 뷰

책 : 뇌를 자극하는 윈도우즈 시스템 프로그래밍

 

1 ) 이름있는 뮤텍스(NamedMutex) 동기화 

 

- 원래 선언된 Mutex는 하나의 프로세스에서 내부 쓰레드들만 사용할 수 있는데, 이름있는 뮤텍스를 사용하면 다른 프로세스들이 그 뮤텍스를 사용할 수 있습니다. 코드를 예시로 확인해 보겠습니다.

 

if 1 -> 이름있는 뮤텍스를 생성하는 코드

else -> 외부 프로세스에서 뮤텍스 접근하여 사용하는 코드

 

예제

더보기
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <tchar.h>

HANDLE hMutex; 
DWORD dwWaitResult;

void ProcessBaseCriticalSection() 
{
	dwWaitResult = WaitForSingleObject(hMutex, INFINITE);

    switch (dwWaitResult) 
    {
        // 쓰레드가 뮤텍스를 소유하였다.
        case WAIT_OBJECT_0:
			_tprintf(_T ("thread got mutex ! \n") );
			break;

        // time-out 발생하였다.
        case WAIT_TIMEOUT: 
			_tprintf(_T ("timer expired ! \n") );
            return; 

        // 뮤텍스 반환이 적절이 이뤄지지 않았다.
        case WAIT_ABANDONED: 
            return; 
    }

	for(DWORD i=0; i<5; i++)
	{
		_tprintf( _T("Thread Running ! \n") );
		Sleep(5000);
	}

	ReleaseMutex(hMutex);
}

int _tmain(int argc, TCHAR* argv[])
{

#if 1
	hMutex = CreateMutex( 
				NULL,                       
				FALSE,                      
				_T("NamedMutex")			
			);								
#else
	hMutex = OpenMutex( 
				MUTEX_ALL_ACCESS,      
				FALSE,                 
				_T("NamedMutex")	   
			 );  

#endif

	if (hMutex == NULL) 
	{
		_tprintf(_T("CreateMutex error: %d\n"), GetLastError());
		return -1;
	}

	ProcessBaseCriticalSection();

	CloseHandle(hMutex);

	return 0;
}

 

2 ) WAIT_ABANDONED

 

- 이건 WaitSingleObject에서 리턴되는 값 중 하나인데, Mutex를 소유하는 쓰레드가 종료하기 전에 소유권을 반환 해줘야 하는데 그렇지 않고 종료하게 되면, Windows에서 이러한 상황을 파악하여 대신 반환해 줍니다. 그럴때 리턴되는 값으로 아래의 코드를 통해서 확인해볼 수 있습니다.

 

예제

더보기
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <tchar.h>

HANDLE hMutex;
LONG gTotalCount = 0;

unsigned int WINAPI IncreaseCountOne(LPVOID lpParm) {
	WaitForSingleObject(hMutex, INFINITE);
	gTotalCount++;

	//Mutex 반환 없이 종료
	return 0;
}

unsigned int WINAPI IncreaseCountTwo(LPVOID lpParm) {
	DWORD dwWaitResult = 0;
	dwWaitResult = WaitForSingleObject(hMutex, INFINITE);

	switch (dwWaitResult) {
	case WAIT_OBJECT_0:
		ReleaseMutex(hMutex);
		break;

	case WAIT_ABANDONED:
		_tprintf(_T("WAIT_ABANDONED \n"));
		break;
	}
	gTotalCount++;

	ReleaseMutex(hMutex);
	return 0;
}
int _tmain(int argc, TCHAR* argv[])
{
	DWORD dwThreadIDOne;
	
	HANDLE hThreadOne;
	HANDLE hThreadTwo;

	hMutex = CreateMutex(NULL, FALSE, NULL);

	if (hMutex == NULL)
		_tprintf(_T("Create Mutex error : %d\n"), GetLastError());

	//무례한 쓰레드
	hThreadOne = (HANDLE)_beginthreadex(NULL, 0, IncreaseCountOne, NULL,
		0, NULL);

	hThreadTwo = (HANDLE)_beginthreadex(NULL, 0, IncreaseCountTwo, NULL,
		CREATE_SUSPENDED, NULL);

	Sleep(1000);
	ResumeThread(hThreadTwo);

	WaitForSingleObject(hThreadTwo, INFINITE);
	_tprintf(_T("total count : %d\n"), gTotalCount);

	CloseHandle(hThreadOne);
	CloseHandle(hThreadTwo);
	CloseHandle(hMutex);

	return 0;
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함