C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[473] TZRunnable 클래스입니다. 클래스에 Thread 를 사용하고 싶을 때 상속하시면 됩니다.
황경록 [mpbox] 7165 읽음    2005-06-23 10:19
-_-빌더로 간단하게만 프로그램을 짜다가 새로 들어온 회사에서 Java 포팅을 하면서
느낀점 아;;; 프로그램 정말 건성건성 짯구나(제가요 ㅎ_ㅎ;;;;;)란 생각이 들더군요;;;
뭐 어차피 고수는 아니지만 @@ 므흣;;;;;
암튼 제목 그대로 입니다.

run 함수만 구현해 주시면 됩니다.

질문은 덧글로....

2005.07.06 수정되었습니다.
^^//

----- 헤더 파일 -----

#ifndef unitZRunnableH
#define unitZRunnableH

#include <Classes.hpp>

class TZRunnable
{
public:
    TZRunnable();
    virtual ~TZRunnable();

private:
    bool m_bTerminated;
    HANDLE m_hThreadHandle;
    unsigned int m_uiThreadID;
    int m_iSuspendCount;

public:
    HANDLE m_hTerminateEvent;
public:
    int getSuspendCount() { return m_iSuspendCount; }
    unsigned int getThreadID() { return m_uiThreadID; }
    bool Terminated();

    //// Main Interface Functions
public:
    void Start();
    void Terminate();
    int  Suspend();
    int  Resume();

    //// Internal Main Thread Entry Point
private:
    static unsigned int WINAPI runInternal(LPVOID lpContext);

    //// Abstract (pure virtual)
public:
    virtual DWORD run() = 0;
};

#endif

----- 소스 파일 ------


#include <process.h>

#include "unitZGConout.h"

#pragma hdrstop

#include "unitZRunnable.h"

#pragma package(smart_init)

/* TODO 1 -onicekr -cOnProgress : TZRunnable::TZRunnable(void) */

TZRunnable::TZRunnable()
{
    m_bTerminated = false;
    m_hThreadHandle = NULL;
    m_hTerminateEvent = NULL;
    m_iSuspendCount = 0;
    m_uiThreadID = 0;   
}

/* TODO 1 -onicekr -cOnProgress : TZRunnable::~TZRunnable(void) */

TZRunnable::~TZRunnable()
{
    if( ! m_bTerminated )
        Terminate();
}

/* TODO 1 -onicekr -cOnProgress : void TZRunnable::Start() */

void TZRunnable::Start()
{
    if( NULL != m_hThreadHandle )
    {
        #ifdef APP_DOUBT
        zout.trace("%s%s\n", APP_DOUBT, "TZRunnable::Run | NULL != m_hThreadHandle");
        #endif

        if( getSuspendCount() )
        {
            Resume();
        }

        return ;
    }

    m_iSuspendCount = 0;
    m_bTerminated = false;
    m_hTerminateEvent = CreateEvent(NULL, true, false, NULL);

    m_hThreadHandle = (HANDLE)_beginthreadex(
        NULL,             // Security
        0,                  // Stack size - use default
        runInternal,      // Thread fn entry point
        (LPVOID)this,
        0,                // Init flag
        &m_uiThreadID     // Thread address
    );

    if( m_hThreadHandle == NULL )
    {
        #ifdef APP_UNEXPECTED
        zout.trace("%s%s\n", APP_UNEXPECTED, "TZRunnable::Run | m_hThreadHandle == NULL");
        #endif
    }
}

/* TODO 1 -onicekr -cOnProgress : void TZRunnable::Terminate(void) */

void TZRunnable::Terminate()
{
    if( true == m_bTerminated )
    {
        #ifdef APP_DOUBT
        zout.trace("%s%s\n", APP_DOUBT, "TZRunnable::Terminate | true == m_bTerminated");
        #endif

        return ;
    }

    SetEvent(m_hTerminateEvent);

    if( WaitForSingleObject(m_hThreadHandle, 15000) == WAIT_TIMEOUT )
    {
        #ifdef APP_DOUBT
        zout.trace("%s%s\n", APP_DOUBT, "TZRunnable::Terminate | WaitForSingleObject(m_hThreadHandle, 15000) == WAIT_TIMEOUT");
        #endif

        DWORD dwExitCode = 0;
        GetExitCodeThread(m_hThreadHandle, &dwExitCode);
        if( ! TerminateThread(m_hThreadHandle, dwExitCode) )
        {
            DWORD dwError = GetLastError();
            #ifdef APP_UNEXPECTED
            zout.printLastError(dwError);
            #endif
        }
    }

    CloseHandle(m_hThreadHandle);
    m_hThreadHandle = NULL;

    CloseHandle(m_hTerminateEvent);
    m_hTerminateEvent = NULL;

    m_uiThreadID = 0;

    m_bTerminated = true;       
}

/* TODO 1 -onicekr -cOnProgress : bool TZRunnable::Terminated() */

bool TZRunnable::Terminated()
{
    if( m_hTerminateEvent != NULL )
    {
        if( WaitForSingleObject(m_hTerminateEvent, 0) == WAIT_OBJECT_0 )
        {
            m_bTerminated = true;
        }
    }

    return m_bTerminated;
}

/* TODO 1 -onicekr -cOnProgress : int TZRunnable::Suspend() */

int TZRunnable::Suspend()
{
    DWORD dwRet = SuspendThread(m_hThreadHandle);

    if(dwRet == 0xFFFFFFFF)
    {
        #ifdef APP_DOUBT
        zout.trace("%s%s\n", APP_DOUBT, "TZRunnable::Suspend | dwRet == 0xFFFFFFFF");
        #endif

        dwRet = GetLastError();

        #ifdef APP_ERROR
        zout.printLastError(dwRet);
        #endif

        return m_iSuspendCount;
    }

    return ++m_iSuspendCount;
}

/* TODO 1 -onicekr -cOnProgress : int TZRunnable::Resume(void) */

int TZRunnable::Resume()
{
    DWORD dwRet = ResumeThread(m_hThreadHandle);

    if(dwRet == 0xFFFFFFFF)
    {
        dwRet = GetLastError();

        return m_iSuspendCount;
    }

    return --m_iSuspendCount;
}

/* TODO 1 -onicekr -cOnProgress : unsigned int WINAPI TZRunnable::runInternal(LPVOID lpContext) */

unsigned int WINAPI TZRunnable::runInternal(LPVOID lpContext)
{
    TZRunnable* pInst = (TZRunnable*)lpContext;
    HANDLE hEnd = pInst->m_hTerminateEvent;

    if( pInst == NULL )
    {
        #ifdef APP_UNEXPECTED
        zout.trace("%s%s\n", APP_UNEXPECTED, "TZRunnable::run | pInst == NULL");
        #endif

        return 0;
    }

    if( hEnd == NULL )
    {
        #ifdef APP_UNEXPECTED
        zout.trace("%s%s\n", APP_UNEXPECTED, "TZRunnable::run | hEnd == NULL");
        #endif

        return 0;
    }

    #ifdef APP_INFO
    zout.trace("%sTZRunnable::run thread[%d] looping start.\n", APP_INFO, pInst->m_uiThreadID);
    #endif

    while( WaitForSingleObject(hEnd, 0) == WAIT_TIMEOUT )
    {
        try
        {
            DWORD dwRet = pInst->run();
           
            Sleep(1000);
        }
        catch( const Exception &e )
        {
            if( e.Message.Length() > 0 )
                zout.trace("%s%s\n", APP_EXCEPTION, e.Message);
        }
    }

    #ifdef APP_INFO
    zout.trace("%sTZRunnable::run thread[%d] terminated.\n", APP_INFO, pInst->m_uiThreadID);
    #endif

    return 0;
}
황경록 [mpbox]   2005-07-06 09:58 X
2005.07.06 수정되었습니다.

+ -

관련 글 리스트
473 TZRunnable 클래스입니다. 클래스에 Thread 를 사용하고 싶을 때 상속하시면 됩니다. 황경록 7165 2005/06/23
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.