출처 : 신경준씨 사외교육 http://blog.naver.com/process3/20052147545
-> Critical section이 Mutex보다 속도가 10배정도 빠르다.
Critical section는 유저모드에서 작동하는 obj이기 때문이며 같은 프로세스안에서만 사용이
가능하다.
- 두개의 Critical section을 돌려도 Mutex보다 빠르다. Critical section은 Count만을 가지고
있으며 Mutex는 커널까지 내려가서 Critical영역에 대한 관리를 요청하기 때문에 느릴 수 밖에
없다.
- 반면에 다른 프로세스에서 다른 프로세스의 자원을 사용할 때는 Mutex를 사용할 수 밖에 없다.
- 정리하자면 Critical section은 같은 프로세스내에서의 임계영역(Critical 영역)을 관리 한다.
(위의 머리말 의미와 동일)
-> 코드2듀오 일때 spinCount를 쓰는 것이 5%정도 더 성능이 올라간다.
-> Critical section내에는 sleep를 쓰지 않는 것을 기본으로 하는데 그대신 이벤트처리를
해도 된다.
[ 세마포어 ]
-> 예제 소스
#include "stdafx.h"
#include
#include "process.h"
#define THREAD_NUM 10
#define INIT_COUNT 0
#define TOTAL_COUNT 10
#define RELEASE_COUNT 1
int g_nIndex = 0;
typedef struct msg_block_tag
{
HANDLE hSemaphore;
} THREAD_ARG;
void PrintTrace()
{
_tprintf(_T("Thread Exit ID = %d|%0x \n"), g_nIndex, GetThreadId(GetCurrentThread()));
g_nIndex++;
}
unsigned int WINAPI TestThread(LPVOID lpThreadData);
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int unThreadId = 0;
THREAD_ARG stThreadArg;
int i = 0;
HANDLE hThread[THREAD_NUM] = {NULL};
LONG lPreviousCount = 0;
stThreadArg.hSemaphore = CreateSemaphore(NULL, INIT_COUNT, TOTAL_COUNT, NULL);
for( i = 0; i < THREAD_NUM; i++)
{
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, TestThread, &stThreadArg, 0, &unThreadId);
}
ReleaseSemaphore(stThreadArg.hSemaphore, RELEASE_COUNT, &lPreviousCount );
WaitForMultipleObjects(THREAD_NUM, hThread, TRUE, INFINITE);
for( i = 0; i < THREAD_NUM; i++)
{
CloseHandle(hThread[i]);
hThread[i] = NULL;
}
CloseHandle(stThreadArg.hSemaphore);
stThreadArg.hSemaphore = NULL;
return 0;
}
unsigned int WINAPI TestThread(LPVOID lpThreadData)
{
THREAD_ARG *lpArg = (THREAD_ARG*)lpThreadData;
DWORD dwThreadStatus = 0;
LONG lPreviousCount = 0;
while(TRUE)
{
dwThreadStatus = WaitForSingleObject(lpArg->hSemaphore, INFINITE);
}
}
return 0;
}
-> 세마포어의 큰 장점은 숫자를 이용할 수 있어 자기가 원하는 쓰레드 수를 고를 수 있다는 점이다.
- 소스를 보면 10개의 쓰레드가 모두 wait상태에서 있다가 하나가 벗어나면
ReleaseSemaphore를 하여 다음 쓰레드에게 알려주게 된다.
- 세마포어의 ReleaseCount를 1로 하면 Mutex와 똑같이 작동을 한다.
- 웹 서버개발시 Mutex와 세마포어를 같이 사용할 수도 있다.
ex) 80개의 쓰레드가 있을 때 Mutex를 쓰면 1개씩 작동을 하므로 나머지 79개가 서로 경쟁
을 하게 되어 비효율적이다. 그러므로 CPU가 8개라면 세마포어를 이용하여 ReleaseCount
를 8개로 주고 Mutex를 이용하여 그 8개끼리 경쟁을 하게 하면 더욱더 효율적으로
구현할 수 있다.( 강의 PPT 15번 참조 )
- 강의 PPT 15번 내용
----------------------------------------------------------------------------------------
Semaphore Throttles (Thundering Herd(놀란 양떼))
하나의 동기화 객체(크리티컬 섹션 또는 뮤텍스)를 기다리는 스레드가
너무 많은 경우, 세마포어를 하나 더 둬서, 해당 동기화 객체를 기다리는
스레드의 숫자를 줄여주는 것이 성능 향상에 도움이 된다.
while (TRUE) { // Worker loop
WaitForSingleObject (hThrottleSem, INFINITE);
WaitForSingleObject (hMutex, INFINITE);
... Synchronization code ...
ReleaseMutex (hMutex);
ReleaseSemaphore (hThrottleSem, 1, NULL);
} // End of worker loop
----------------------------------------------------------------------------------------