#include <windows.h>
#include <process.h>
#include <iostream>
#include <stdio.h>
using namespace std;
#define MAX_THREAD 3
static int h = 1;
CRITICAL_SECTION a;
DWORD WINAPI func1(LPVOID test){
int f = (int)test;
EnterCriticalSection(&a);
h = h+1;
printf("num f : %d\n",f);
printf("num h : %d, %d\n\n",f,h);
LeaveCriticalSection(&a);
//f = (int)test;
/*if(f == 1){
printf("babo\n");
}else if(f==2){
printf("ddonggae\n");
}else
printf("num : %d\n",f);
*/
return 0;
}
int main(int argc, char **argv)
{
DWORD dwID;
HANDLE h[5];
int i = 0;
InitializeCriticalSection(&a);
for(i=0;i<5;i++){
printf("CreateThread Start : %d\n",i);
h[i] = CreateThread(NULL,0,func1,(LPVOID)i,0,&dwID);
// Sleep(1000);
printf("CreateThread End : %d\n",i);
}
printf("Waiting for thread...\n");
//WaitForSingleObject(h[0],INFINITE);
WaitForMultipleObjects(5,h,TRUE,INFINITE);
DeleteCriticalSection(&a);
for(i=0;i<5;i++){
CloseHandle(h[i]);
}
printf("Terminated Program\n");
Sleep(50000);
return 0;
}
크리티컬 섹션은 내부적으로 '무거운 커널 오브젝트' 인 세마포어로 구현되어 있습니다. 다만 일반적인 경우에 크리티컬 섹션이 빠른 이유는 간섭이 없어서 락이 필요하지 않을경우 세마포어를 사용하지 않는 트릭을 사용하기 때문입니다. - 간섭이 없을경우 세마포어는 아예 생성조차 되지 않습니다 -
크리티컬 섹션의 동작을 간단히 설명해 보면
1. 아무도 소유하지 않은 critical section 인 경우 별다른 처리 없이 바로 진입된다. - 그래서 빠르다..!!
2. critical section 을 다른 쓰레드가 이미 소유하고 있다면 세마포어를 만든다. 그리고 WaitForSingleObject() 로 대기모드 돌입.
3. 이미 enter 했던 critical section 은 leave 할때 대기중인 세마포어가 있으면 그녀석에게 이벤트를 날려주고 leave 한다.
4. 그러면 이제 깨어난 녀석은 다시 자기가 enter.. 하고 이런식.
VC++ 디버그 시 Watch 창에 CRITICAL_SECTION 구조체를 올려놓고 확장해 보면 세마포어 핸들이 있습니다. 락 간섭이 없을경우 NULL 이고 간섭이 한번이라도 일어나면 세마포어가 핸들이 할당되는것을 확인할 수 있습니다.
출처 : http://blog.naver.com/mind2on/90006173711