본문 바로가기
WORK/Sotfware

MFC Thread 완전정복 2 - Thread 종료하기

by KANG Stroy 2008. 6. 2.
728x90
728x90

--UI Thread
call AfxEndThread.
post WM_QUIT.( ::PostQuitMessage )

(쓰레드 종료함수 사용시 주의할것은 쓰레드 내부에 메모리를 동적할당(new,malloc)해놓고 delete를 안해서 메모리 릭이 날 염려가 있다. 그래서 가급적이면 쓰레드 함수 리턴으로 종료하는 것이 낫다.)

위의 함수들을 호출한 후 한번 제대로 종료됬는지 확인해보라
DWORD dwExitCode;
::GetExitCodeThread (pThread->m_hThread, &dwExitCode);

만약 여전히 살아 있다면 dwExitCode = STILL_ACTIVE(0x103) 으로 되어 있을테다.



- CWinThread 개체 자동 삭제하기

AfxBeginThread 로 스레드 생성할 경우,


CWinThread *pThread = AfxBeginThread( , ,, );


위와 같이 CWinThread 개체 포인터를 반환값으로 받는다. 스레드 종료시, 이 개체는 어떻게 되는가?

MFC는 사용자가 따로 delete pThread; 할 필요없게 자동으로 삭제해 준다.

그런데, 여기서 문제가 있다.

스레드가 종료되지 않았다면, 아래구문은 잘못된 곳이 없다.


::GetExitCodeThread( pThread->m_hThread, &dwExitCode );

( 스레드의 현재 상태값을 반환하는 함수 )


하지만, 종료되어 pThread 개체 포인터 역시 자동으로 삭제되었다면, 위의 구문은 에러를 발생할 것인다.

pThread 는 아무것도 가리 키지 않기 때문에..


해결책)

1. m_bAutoDelete = FALSE; 설정.

-- 이는 곧 사용자가 CWinThread 개체를 delete 해주어야 함을 의미한다.

-- 스레드가 중지가 된 상태에서 m_bAutoDelete = FALSE; 를 설정해주어야 한다.


2. Win32::DuplicateHandle 함수를 호출하여 스레드 핸들의 사본을 생성하여 사용.

-- 해당핸들의 참조카운트가 1 -> 2로 증가되어 CloseHandle() 호출시에 다시 2 -> 1 로 감소될뿐 개체는 죽지 않고 남아있다. 물론, 사용자가 명시적으로 CloseHandle() 을 호출해야 한다.


- 다른 스레드 종료하기

1.

//Thread A

nContinue = 1;

CWinThread *pThread = AfxBeginThread( ThreadFunc, &nContinue );

...

...

nContinue = 0 ; // 스레드 B 를 종료해라.



//Thread B

UINT ThreadFunc( LPVOID pParam )

{

  int* pContinue = (int*) pParam;

  while( *pContinue )

  {

    ....

  }

  return 0;

}


2. 스레드 A는 스레드 B가 죽을때 까지 무한 기다리도록 하고 싶을 경우,


//Thread A

nContinue = 1;

CWinThread *pThread = AfxBeginThread( ThreadFunc, &nContinue );

HANDLE hThread = pThread->m_hThread; //사본 생성. 스레드B종료시 pThread 없을 경우 대비.

...

...

nContinue = 0 ; // 스레드 B 를 종료해라.

::WaitForSingleObject( hThread, INFINITE );

//Thread B

//1.의 에제와 같음

::WaitForSingleObject 은 hThread 스레드가 종료될때 까지 무한정(INFINITE) 기다리는 함수이다.  반환 값은 아래와 같다.

-- WAIT_OBJECT_0 : 그 개체가 신호를 받았다. 즉, 스레드가 종료되었다.

-- WAIT_TIMEOUT : 스레드는 살아있지만, 시간 만료로 기다리지 않고 반환되었다.


두번째 매개 변수를 0 으로 설정하고 아래와 같이 사용하는 것이 좋다.


if( ::WaitForSingleObject( hThread, 0 ) == WAIT_OBJECT_0 )

//스레드가 더이상 존재치 않는다.

else

//스레드가 여전히 실행중이다.



- ::TerminateThread( hThread, 0 );

다른 스레드를 직접삭제하는 방법은 위의 함수 딱 한가지 존재한다. 어쩔 수 없는 경우에만 사용하도록 .

728x90

'WORK > Sotfware' 카테고리의 다른 글

Edit Clear  (0) 2008.06.02
RS232 통신  (0) 2008.06.02
MFC Thread 완전정복 ( 마지막 )  (0) 2008.06.02
MFC Thread 완전정복 3 - 동기화  (0) 2008.06.02
MFC Thread 완전정복 1(펌)  (0) 2008.06.02

댓글