Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Hyper-V
- go.mod
- Windows
- 레파지토리
- asyncio
- apt-get
- FastAPI
- pip
- repo
- Finance
- 자식프로세스
- mariadb
- Thread
- BATCH
- 파이썬
- golang
- APT
- Replication
- 가상화 중첩화
- QT_QPA_PLATFORM_PLUGIN_PATH
- 스트리밍
- dockercontainer
- psutil
- 영상스트리밍
- 주식
- go
- python3.9
- docker
- Python
- 자원측정
Archives
- Today
- Total
검색하기귀찮아서만든블로그
AfxBeginThread 이벤트 클래스 본문
/*
제가 주로 사용하는 스레드 클래스입니다.
단일 스레드 구조로 만들었고 WaitForSingleObject 보다 WaitForMultiObject 를 주로 사용합니다.
스레드는 종료 이벤트와 사용자 이벤트를 대기합니다. 100ms 마다 타임아웃 동작을 합니다.
스레드 종료 시 최대 1초까지 스레드 종료를 대기하는 구조로 되어있습니다.
1. 스레드 생성 : MakeThread()
2. 스레드 사용자 동작 : SetUserThreadEvent()
3. 스레드 종료 : KillThread()
*/
#include "stdafx.h"
#include "afxwin.h"
///////////////////////////////////////////////////////////////////////////
// 헤더에 정의해도 무방
// 스레드 파라미터 구조체
typedef struct _stThreadParam
{
CWnd* pParent; // 클래스 포인터
HANDLE hProcEvent; // 스레드 동작 이벤트
HANDLE hEndEvent; // 스레드 종료 이벤트
BOOL bThreadEnd; // 스레드 종료 여부
void* pThread; // 스레드 클래스 포인터
// 구조체 생성자
_stThreadParam()
{
pParent = NULL;
hProcEvent = NULL;
hEndEvent = NULL;
bThreadEnd = FALSE;
pThread = NULL;
}
// 구조체 소멸자
~_stThreadParam()
{
// 스레드 이벤트들을 소멸한다.
SAFE_CLOSEHANDLE(hProcEvent);
SAFE_CLOSEHANDLE(hEndEvnet);
}
}STThreadParam, *LP_STThreadParam;
// 포인터 삭제 메소드
#define SAFE_DELETE(x) {if(x) delete x; x=NULL;}
#define SAFE_CLOSEHANDLE(x) {if(x) CloseHandle(x); x=NULL;}
///////////////////////////////////////////////////////////////////////////
// 상수 정의
const UINT THREAD_EVENT_COUNT = 2; // 스레드 이벤트 카운트
const UINT THREAD_WAIT_TIMEOUT = 100; // 스레드 대기 시간 ms
// 글로벌 변수 (클래스 멤버 변수로 정의 해도 무방)
LP_STWebCheckerThreadParam m_pThreadParam = NULL; // 스레드 파라미터 저장용 구조체 포인터
/*============================================================================
* 함 수 : MakeThread
*---------------------------------------------------------------------------
* 출 력 : void
*---------------------------------------------------------------------------
* 설 명 : 클래스 생성자
*===========================================================================*/
CTestClassName::CTestClassName()
{
m_pThreadParam = NULL;
}
/*============================================================================
* 함 수 : MakeThread
*---------------------------------------------------------------------------
* 출 력 : void
*---------------------------------------------------------------------------
* 설 명 : 클래스 소멸자
*===========================================================================*/
CTestClassName::~CTestClassName()
{
KillThread();
}
/*============================================================================
* 함 수 : _ThreadProc
*---------------------------------------------------------------------------
* 출 력 : UINT WINAPI
*---------------------------------------------------------------------------
* 설 명 : 스레드 프로시저
*===========================================================================*/
UINT WINAPI CTestClassName::_ThreadProc(LPVOID pParameter)
{
LP_STWebCheckerThreadParam pParam = (LP_STWebCheckerThreadParam)pParameter;
CTestClassName* pMain = (CTestClassName*)pParam->pParent;
HANDLE hEvents[THREAD_EVENT_COUNT] = { pParam->hEndEvent, pParam->hProcEvent };
DWORD dwEvent = WAIT_FAILED;
while (TRUE)
{
dwEventRet = WaitForMultipleObjects(THREAD_EVENT_COUNT, hEvents, FALSE, THREAD_WAIT_TIMEOUT);
// 대기 실패, 또는 종료이벤트가 발생하면 while 루프를 빠져나간다.
if (WAIT_FAILED == dwEventRet || WAIT_OBJECT_0 == dwEventRet)
{
break;
}
// 사용자가 설정한 이벤트가 발생했을 때
if (WAIT_OBJECT_0 + 1 == dwEventRet)
{
///////////////////////////////////////////////
// 이벤트가 발생했을 때 동작을 구현하시면 되요 ~
// 클래스에 접근하시고 싶으면 pMain 를 사용하시면 됩니다.
///////////////////////////////////////////////
continue;
}
///////////////////////////////////////////////
// 타임아웃 되었을 때 동작 구현하시면 되요 ~
// 아무것도 안할 꺼면 THREAD_WAIT_TIMEOUT 값을 INFINITE 로 변경하세요.
///////////////////////////////////////////////
}
// 스레드가 종료 된다는 플래그를 TRUE 로 바꿔준다. (종료를 대기하고 있는 프로세스를 위해서)
pParam->bThreadEnd = TRUE;
return 0;
}
/*============================================================================
* 함 수 : MakeThread
*---------------------------------------------------------------------------
* 출 력 : void
*---------------------------------------------------------------------------
* 설 명 : 스레드 생성
*===========================================================================*/
void CTestClassName::MakeThread()
{
// 기존에 생성된 스레드가 있을 경우 종료 시킨다.
KillThread();
// 스레드 파라미터 구조체 생성
LP_STWebCheckerThreadParam pParam = new STWebCheckerThreadParam;
// 파라미터 구조체에 클래스 포인터와, 스레드 동작 이벤트, 스레드 종료이벤트를 생성한다.
pParam->pParent = this;
pParam->hProcEvent = CreateEvent(TRUE, NULL, NULL FALSE);
pParam->hEndEvent = CreateEvent(TRUE, NULL, NULL FALSE);
// 스레드 생성
CWinThread* pThread = (void*)AfxBeginThread((AFX_THREADPROC)_ThreadProc, (void*)pParam);
if (pThread == NULL)
{
return;
}
pParam->pThread = (void*)pThread;
// 스레드 파라미터를 멤버 포인터 변수에 기록한다.
m_pThreadParam = pParam;
}
/*============================================================================
* 함 수 : MakeThread
*---------------------------------------------------------------------------
* 출 력 : void
*---------------------------------------------------------------------------
* 설 명 : 스레드에게 사용자가 지정한 동작을 하도록 이벤트를 활성화 한다.
*===========================================================================*/
void CTestClassName::SetUserThreadEvent()
{
// 스레드 파라미터 포인터가 NULL 이면 함수를 반환한다. (예외 처리)
if (NULL == m_pThreadParam)
{
return;
}
SetEvent(m_pThreadParam->hProcEvent);
}
/*============================================================================
* 함 수 : MakeThread
*---------------------------------------------------------------------------
* 출 력 : void
*---------------------------------------------------------------------------
* 설 명 : 스레드를 종료하도록 이벤트를 활성화 한다.
*===========================================================================*/
void CTestClassName::KillThread()
{
// 스레드 파라미터 포인터가 NULL 이면 함수를 반환한다. (예외 처리)
if (NULL == m_pThreadParam)
{
return;
}
// 스레드 종료 이벤트를 활성화 한다.
SetEvent(m_pThreadParam->hEndEvent);
// 스레드가 종료 될 때 까지 최대 1초를 대기한다.
for (int i = 0; i < 100 && FALSE == m_pThreadParam->bThreadEnd; i++)
{
Sleep(10);
}
// 스레드가 종료되지 않을 경우 강제 종료한다.
// 참고 : 스레드가 빨리 종료되지 않고 여기서 강제 종료될 경우 메모리릭 발생 소지 있음
// 가급적이면 스레드의 처리 루틴을 간결하게 작성하여 종료 이벤트를 빨리 처리할 수 있도록 해야 한다.
if (FALSE == m_pThreadParam->bThreadEnd)
{
CWinThread* pThread = (CWinThread*)m_pThreadParam->pThread;
DWORD dwExitCode = 0;
GetExitCodeThread(pThread->m_hThread, &dwExitCode);
TerminateThread(pThread->m_hThread, dwExitCode);
}
// 스레드 파라미터 객체를 소멸한다.
SAFE_DELETE(m_pThreadParam);
}
'개발' 카테고리의 다른 글
[python] multiprocessing 사용법 (0) | 2022.04.02 |
---|---|
[python] fast api 영상 relay server (0) | 2021.12.04 |
[python] fastAPI 카메라 MJEPG 스트리밍 (0) | 2021.10.09 |
[python] fastAPI 입문 (0) | 2021.10.08 |
[python] PyQt5 UI 프로그램 개발 환경 구성하기 (0) | 2021.06.08 |