티스토리 뷰
책 : 뇌를 자극하는 윈도우즈 시스템 프로그래밍
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;
}
'서버 공부 > 시스템 프로그래밍' 카테고리의 다른 글
메모리 관리 - 힙(Heap) 컨트롤 (0) | 2022.07.29 |
---|---|
쓰레드 동기화 기법 - NamedMutex와 WAIT_ABANDONED (0) | 2022.07.29 |
쓰레드 동기화 기법 - 유저 모드 동기화 (0) | 2022.07.28 |
쓰레드 구현 모델 (0) | 2022.07.28 |
(IPC통신) Named Pipe 통신 (0) | 2022.07.27 |
댓글