본문 바로가기
프로그래밍/MFC (C++)

MFC ] 쓰레드의 생성 및 시작, 종료, 일시 중단, 재개

by eteo 2022. 9. 18.

 

 

-Dlg.h 파일에 쓰레드 핸들링을 위한 변수 선언

 

typedef enum {
	THREAD_STOP,
	THREAD_RUNNING,
	THREAD_PAUSE
}_ThreadStatus;

//...
public:
    CWinThread* m_pThread;
    _ThreadStatus m_threadStatus;

 

 

 

 

쓰레드 함수 전역으로 정의

만약 메인 함수로 정의하려면 앞에 static 을 붙여야 한다. 함수 앞에 static을 붙이면 전역으로 취급되지만 해당 소스파일 내에서만 호출할 수 있다.

 

UINT ThreadRepeat(LPVOID LpData)
{

	CdeltaControlDlg* pDlg = (CdeltaControlDlg*)(LpData);
	vector<DataRow*>& refList = pDlg->DC.getList();

	while (pDlg->m_threadStatus == THREAD_RUNNING)
	{
		//...
	}

	return 0;
}

 

 

 

 

 

 

 

쓰레드의 생성 및 시작 또는 중단상태인 쓰레드를 재개

 

void CdeltaControlDlg::OnBnClickedButtonRun()
{

	if (m_pThread == NULL) 
	{	

		m_pThread = AfxBeginThread(ThreadRepeat, (LPVOID)this);
		if (m_pThread == NULL)
		{
			AfxMessageBox(_T("ERROR : Fail to begin thread."));
		}
		else 
		{
			m_pThread->m_bAutoDelete = FALSE;
			m_threadStatus = THREAD_RUNNING;
		}
	}
	else if (m_threadStatus == THREAD_PAUSE) 
	{
		m_pThread->ResumeThread();
		m_threadStatus = THREAD_RUNNING;
	}

}

 

CWinThread 객체의 멤버 변수인 m_bAutoDelete는 디폴트값이 TRUE이고 TRUE일 때 쓰레드 종료 시 자동으로 삭제 된다. 해당 값을 FALSE로 설정하면 쓰레드 종료 시 자동삭제를 방지하고 사용자가 CWinThread 객체를 delete 해주어야 한다는 뜻이다. 쓰레드 종료 후에도 핸들로 접근해서 처리할 일이 있을 때 쓰이는 방법이다.

 

 

 

 

 

 

 

쓰레드 일시 중단

 

void CdeltaControlDlg::OnBnClickedButtonSuspend()
{
	if (m_pThread != NULL) 
	{
		m_pThread->SuspendThread();
		m_threadStatus = THREAD_PAUSE;
	}
	
}

 

 

 

 

 

 

 

 

쓰레드 종료

 

void CdeltaControlDlg::OnBnClickedButtonStop()
{
	terminateThread();
}

void CdeltaControlDlg::terminateThread()
{
	if (m_pThread != NULL)
	{
		//...
		m_pThread->SuspendThread();
		DWORD dwResult;
		GetExitCodeThread(m_pThread->m_hThread, &dwResult);

		delete m_pThread;
		m_pThread = NULL;
		m_threadStatus = THREAD_STOP;
		//...
	}
}

 

쓰레드의 종료는 ON_DESTORY 함수에도 써줘야 하고 Com Port를 쓰는 쓰레드라 시리얼 통신이 종료됐을 때도 써줘야 하고 여기저기 쓸 일이 많아서 함수화했다.

 

 

 

 

 

 

 

Reference : https://m.blog.naver.com/mincheol9166/220718941148