본문 바로가기

Programming/MFC

WaitForSingleObject

static HANDLE hAaaa;

hAaaa=CreateEvent(NULL,TRUE, FALSE,NULL);

......

 

WaitForSingleObject(hAaaa,INFINITE);

......

 

다른 뜨레드에서, 또는 콜백함수 안에서

SetEvent(hAaaa);

 

 

 

 

 

웨이트퍼싱클오브젝트 안의 두번째 인자가 INFINITE 이므로 hAaaa 가 이벤트를 받을때까지 무한정 기다립니다.

여기다가 시간을 넣을 수도 있습니다. 1000  이라고 넣으면 1초를 기다립니다.

2000을 넣으면 2초동안 hAaaa이벤트를 기다립니다. 이시간안에 이벤트가 오면 다음줄로 진행하고요, 이벤트가 오지않아 2초가 지나가면 역시

다음줄로 진행합니다.

INFINITE  를 넣으면 시간을 정해놓고 기다리지 않고 무한정 기다립니다.

hAaaa에 신호(이벤트)를 주려면 어디에서인가 SetEvent(hAaaa);  를 해주어야 합니다.

SetEvent(hAaaa);  를 어디에서인가 실행하면 WaitForSingleObject(hAaaa , INFINITE );  가 신호를 받아서 다음줄로 진행합니다.

의문 1  : 어디에서 SetEvent(hAaaa);  를 실행할 것인가?

           가정1) : WaitForSingleObject(hAaaa , INFINITE );  앞에서

                      이렇게 하면 이미 hAaaa가 신호를 받았기때문에  

                      WaitForSingleObject(hAaaa , INFINITE ); 여기에 도달하면 조건이 만족하여(신호가 와서 = signaled 라고 합니다 ) 기다리지

                      않고 다음줄로 진행합니다.  WaitForSingleObject(hAaaa , INFINITE );  가 없다고 해도 진행(다음줄로 간다는 의미)하고 ,

                      있다고 해도 진행합니다.

                      가정1 결론 : WaitForSingleObject(hAaaa , INFINITE );   있으마 마나한 코드입니다.

          가정2) :  WaitForSingleObject(hAaaa , INFINITE );   뒤에서

                      이렇게 하면 WaitForSingleObject(hAaaa , INFINITE );  hAaaa가 아직 signal되지(켜지지) 않았기 때문에 hAaaa이

                      켜지게(signaled) 되기를 기다립니다 , 얼마동안 --> 무한정 ( signaled 될때까지)  그러나 hAaaa를 켜지게 하는 코드(SetEvevt)는

                      WaitForSingleObject(hAaaa , INFINITE ); 뒤에 있으므로  컴퓨터 전원 끌때까지 기다립니다.

                      가정2 결론 :WaitForSingleObject(hAaaa , INFINITE ); 여기에서 진행시점이 멈춰 있습니다. 더이상 진행하지 못합니다.

 

         그럼 어디에서 신호를 줘야 하나?

                     웨이트퍼싱글오브젝트가 있는 뜨레드가 아닌 다른 뜨레드 안에서는 SetEvent(hAaaa) ;를 넣어 줍니다.

 

 

CreateEvent( NULL, TRUE, FALSE, NULL );  안의 2번째 인자를 어떻게 주냐에 따라 hAaaa의 신호가 자동으로 꺼지지는, 수동으로 꺼지는

지를 결정합니다.  TRUE를 주면 수동으로 꺼주게 되는 경우 입니다.

 꺼주는 명령어는 ResetEvent(핸들) 입니다.    여기서는 ResetEvent(hAaaa);  이렇게 쓰면 됩니다.

 

가장간단한 예제를 보겠습니다.(예제는 화일을 다운 하세요).

 

이 예제는 다이얼로그 베이스 프로그램으로서 두개의 버튼을 가집니다.

하나는 소리나기, 다른 하나는 소리안나기 입니다.

소리나기를 누르면 웨이트퍼싱글오브젝트로 흐름을 멈춘것을 풀어서 소리를 나게 하고, 소리안나기 버튼을 누르면  소리가 안나게 됩니다.

소리 나게 하는 부분은 다음과 같습니다.

for(;;)

{

   WaitForSingleObject(핸들, 기다리는시간);

   Beep(100,100);

   Sleep(500);    

}

 

간단하죠?  비프로 소리를 나게 하고 0.5초 동안 멈춥니다. 이것을 포 루프로 감싼 것입니다.

   

          선수학습 1 : 간단한뜨레드 만들기

                  뜨레드실행하기        --> AfxBeginThread(뜨레드함수이름, 인자);

                  선언(*.h  안에서    ) --> static UINT 뜨레드이름(void* lParam);

                  구현(*.cpp  안에서) --> UINT 클래스이름::뜨레드함수이름(LPVOID lParam)

                                                    {

                                                        ....

                                                        ....

                                                     }

 

        선수학습2 : CreateEvent  2번째 인자

                 CreateEvent(NULL,TRUE, FALSE,NULL);

                 2번째 인자는 신호끄기(unsignaled)를 수동으로 할것인지, 안할것인지(자동으로함) 를 결정하는 값입니다.

                 FALSE(자동)으로 하면 웨이트퍼싱글오브젝트를 벗어날때 켜진신호(signaled)가  자동으로 꺼(unsignaled) 집니다.

                 TRUE(수동) 으로 했다면 , ResetEvent()를 실행하여 해야 신호가 꺼집니다.

                 참고로 웨이트퍼멀티플오브젝트에서도 사용밥법은 같습니다. 웨이트멀티플오브젝트는 여러개의 이벤트를 기다리는 함수입니다.

                 

       

 

 

우리는 위의 소리나는부분을 뜨레드로 돌릴것입니다.

그러므로 뜨레드안의 ....   이 부분에 소리나는 부분을 넣어야 합니다.

뜨레드의 실행은 다이얼로그가 초기화할때 할것입니다.

이렇게...

 

BOOL CTeach_waitobjectDlg::OnInitDialog()

{

   ....

   ....

   // TODO: Add extra initialization here

    AfxBeginThread(beep_sleep,this);                         <---------------------  이 부분

    ....

}

여기서 beep_sleep  가 뜨레드함수 이름 입니다.

 

또한 여기에서 이벤트 핸들을  생성할것입니다. 2번재 인자는 수동복구(TRUE)로 할것입니다.

( 이벤트핸들을 생성하기전에 이벤트핸들을 선언해야합니다. (*.h)에  해야 합니다. --->  static HANDLE 핸들이름 = static HANDLE hCampain;)

( 과제:  자동복구(FALSE)로 했을경우를 예상하세요. 정답은 밑에 써 놓을게요)

이렇게....

BOOL CTeach_waitobjectDlg::OnInitDialog()

{

   ....

   ....

   // TODO: Add extra initialization here

    hCampain=CreateEvent(NULL,TRUE,FALSE,NULL);         <-----------------  이 부분

    AfxBeginThread(beep_sleep,this);

    ....

}

 

소리나기 버튼을 크릭하면 OnButton1()  메세지가 발생되어 정의되어진 핸들러(함수)가 실행됩니다.

우리가 하고 있는 예제에서는 함수내용이 이벤트에 신호(signaled)를 줄것입니다.

이렇게.....

{

    SetEvent(이벤트핸들);

}

 

소리안나기 버튼을 크릭하면OnButton2() 메세지가 발생되어 정의되어진 핸들러(함수)가 실행됩니다.

우리는 여기에서 이벤트에 신호끄기(unsignaled)를 할것입니다.

이렇게....

{

   ResetEvent(이벤트핸들);

}

 

 

여기가지입니다.

예제를 다운해서 실행해 보세요.

또한 위에서 내준 과제를 검증하기 위해서 소스의 CreateEvent  2번째 인자를 자동(FALSE)로 고쳐서 실행도 해보세요.( 이문장이 과제의 해답)

 

결론

 

WaitForSingleObject(핸들, 기다리는시간);

이것은 핸들이 signaled 가 되면 벗어나는 함수(시간을 기다리는 뜨레드 라고 생각해도 됨)로서 기다리는 시간을 0 이상의 숫자(단위는 1000분의 1초)로 주었을 경우에는 주어진 시간안에서 이벤트를 기다리다 이 시간이 경과 하면 벗어나게 됩니다. 기다리는시간에INFINITE 를 주면 시간제한 없이 기다리게 됩니다.

 

 

 

WAIT_TIMEOUT -> 아직 쓰레드가 실행중

WAIT_OBJECT_0 -> 쓰레드가 종료되었음.

WAIT_FAILED -> 함수 실패

'Programming > MFC' 카테고리의 다른 글

_CrtSetBreakAlloc()으로 메모리릭 디버깅하기.  (0) 2006.02.07
확장 DLL 만들기  (0) 2006.02.07
CRITICAL_SECTION  (0) 2006.02.06
GetText  (0) 2006.02.06
ResetContent  (0) 2006.02.06