티스토리 뷰

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

 

1 ) 뮤텍스(Mutex) 기반 동기화 

 

- 뮤텍스 생성

hMutex = CreateMutex(
		NULL,     // 디폴트 보안관리자.
		FALSE,    // 누구나 소유 할 수 있는 상태로 생성. 
		 	  //(TRUE일 경우, 뮤텍스를 생성하는 쓰레드가기회를 얻음)
		NULL      // numaned mutex
	);

- Mutex 사용

WaitForSingleObject(hMutex, INFINITE);
/*********************
임계영역
*********************/
ReleaseMutex(hMutex);

 

예제

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

#define NUM_OF_GATE		6

LONG gTotalCount = 0;

// CRITICAL_SECTION   gCriticalSection;
HANDLE hMutex;

void IncreaseCount()
{
	WaitForSingleObject(hMutex, INFINITE);

	gTotalCount++;

	ReleaseMutex(hMutex);
}


unsigned int WINAPI ThreadProc( LPVOID lpParam ) 
{ 
	for(DWORD i=0; i<1000; i++)
	{
		IncreaseCount();
	}

	return 0;
} 


int _tmain(int argc, TCHAR* argv[])
{
	DWORD dwThreadIDs[NUM_OF_GATE];
	HANDLE hThreads[NUM_OF_GATE];

	//	InitializeCriticalSection(&gCriticalSection);
	hMutex = CreateMutex(
		NULL,     // 디폴트 보안관리자.
		FALSE,    // 누구나 소유 할 수 있는 상태로 생성.
		NULL      // numaned mutex
	);

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

	for (DWORD i = 0; i < NUM_OF_GATE; i++)
	{
		hThreads[i] = (HANDLE)
			_beginthreadex(
				NULL,
				0,
				ThreadProc,
				NULL,
				CREATE_SUSPENDED,
				(unsigned*)&dwThreadIDs[i]
			);

		if (hThreads[i] == NULL)
		{
			_tprintf(_T("Thread creation fault! \n"));
			return -1;
		}
	}

	for (DWORD i = 0; i < NUM_OF_GATE; i++)
	{
		ResumeThread(hThreads[i]);
	}


	WaitForMultipleObjects(NUM_OF_GATE, hThreads, TRUE, INFINITE);

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

	for (DWORD i = 0; i < NUM_OF_GATE; i++)
	{
		CloseHandle(hThreads[i]);
	}

	//	DeleteCriticalSection(&gCriticalSection);
	CloseHandle(hMutex);

	return 0;
}

 

1 ) 세마포어(Semaphore) 기반 동기화 

 

- 다른점은 임계영역을 사용할 쓰레드를 여러개 지정할 수 있다. 무슨 소리인가 하면, Mutex같은 경우 임계영역을 사용할 수 있는 쓰레드는 1개로 제한되지만, 세마포어 같은 경우에는 지정한 갯수의 쓰레드가 동시에 임계영역을 실행할 수 있다.

 

- 세마포어 생성 함수

hSemaphore = CreateSemaphore (
                   NULL,           // 디폴트 보안관리자.
                   TABLE_CNT,      // 세마포어 초기 값. (임계 영역에 접근 가능한 쓰레드 개수)
                   TABLE_CNT,      // 세마포어 최대 값.
                   NULL            // unnamed 세마포어 구성.
		         );

- 세마포어 사용

WaitForSingleObject(hSemaphore, INFINITE);
/*********
임계영역
*********/
ReleaseSemaphore(hSemaphore, 1, NULL);

 

예제

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

#define NUM_OF_CUSTOMER 50
#define RANGE_MIN 10
#define RANGE_MAX (30 - RANGE_MIN)
#define TABLE_CNT 10


HANDLE hSemaphore;
DWORD randTimeArr[50];

void TakeMeal(DWORD time)
{
	WaitForSingleObject(hSemaphore, INFINITE);
	_tprintf( _T("Enter Customer %d~ \n"), GetCurrentThreadId());

	_tprintf(_T("Customer %d having launch~ \n"), GetCurrentThreadId());
	Sleep(1000 * time);	// 식사중인 상태를 시뮬레이션 하는 함수.

	ReleaseSemaphore(hSemaphore, 1, NULL);
	_tprintf( _T("Out Customer %d~ \n\n"), GetCurrentThreadId());
}


unsigned int WINAPI ThreadProc( LPVOID lpParam ) 
{ 
	TakeMeal((DWORD)lpParam);
	return 0;
}


int _tmain(int argc, TCHAR* argv[])
{
    DWORD dwThreadIDs[NUM_OF_CUSTOMER];
    HANDLE hThreads[NUM_OF_CUSTOMER];
   
	srand( (unsigned)time( NULL ) );  	// random function seed 설정


	// 쓰레드에게 전달할 random 값 총 50개 생성.
	for(int i=0; i<NUM_OF_CUSTOMER ;i++)
	{
        randTimeArr[i] = (DWORD) (
				((double)rand() / (double)RAND_MAX) * RANGE_MAX + RANGE_MIN
			);
  	}

	// 세마포어 생성.
    hSemaphore = CreateSemaphore (
		           NULL,    // 디폴트 보안관리자.
                   TABLE_CNT,      // 세마포어 초기 값.
                   TABLE_CNT,      // 세마포어 최대 값.
				   NULL     // unnamed 세마포어 구성.
		         );
    if (hSemaphore == NULL) 
    {
        _tprintf(_T("CreateSemaphore error: %d\n"), GetLastError());
    }


	// Customer를 의미하는 쓰레드 생성.
	for(int i=0; i<NUM_OF_CUSTOMER; i++)
	{
        hThreads[i] = (HANDLE)
		    _beginthreadex ( 
			    NULL,
			    0,				        
			    ThreadProc,				  
			    (void*)randTimeArr[i],                    
			    CREATE_SUSPENDED,		   
			    (unsigned *)&dwThreadIDs[i]   
	        );

	    if(hThreads[i] == NULL)
	    {
	        _tprintf(_T("Thread creation fault! \n"));
	        return -1;
	    }
	}

	for(int i=0; i<NUM_OF_CUSTOMER; i++)
	{
		ResumeThread(hThreads[i]);
	}

	WaitForMultipleObjects(NUM_OF_CUSTOMER, hThreads, TRUE, INFINITE);

    _tprintf(_T("----END-----------\n"));

	for(int i=0; i<NUM_OF_CUSTOMER; i++)
	{
		CloseHandle(hThreads[i]);
	}
	
	CloseHandle(hSemaphore);

	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
글 보관함