#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




+ Recent posts