잊지 않겠습니다.

'C++'에 해당되는 글 1건

  1. 2009.01.07 Object Threading

Object Threading

OS 자료들 2009. 1. 7. 13:10

스레드 Windows API 함수를 클래스로 래퍼(Wrapper)해서 쓰는 방법에 대해 소개하겠습니다. MFC에 있는 객체 스레드에서 워커 스레드로 구현할 때 MFC 객체 스레드는 너무 무겁게 느껴질 것입니다. 그 대안으로 객체 스레드를 구성해 보았습니다. 이 스레드는 워커 스레드용으로써, 이 스레드를 잘 활용하면 가장 깔끔하고 간단하면서도 강력하게 구현될 것입니다.

  객체 스레딩 기법의 재사용성에 맞추어 구현해 보도록 하겠습니다. 기반 클래스(Base Class)를 CThread라고 가정하고 다음과 같이 구현합니다.

  객체 스레딩 기법의 객체 스레드 선언 부분은 다음과 같다.

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

    virtual void Create();
    virtual void Stop();

    BOOL IsRunning() { return m_hThread != NULL; } const

    virtual DWORD OnThreadProc() = 0;
    static DWORD WINAPI ThreadProc(LPVOID lpParam);

    static int GetRefCount() { return m_nRef; } const
    int GetIndex() { return m_nIndex; } const

protected:
    HANDLE m_hThread;
    DWORD m_dwThreadId;

private:
    static int m_nRef;
    int m_nIndex;
};

  

  

int CThread::m_nRef = 0;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CThread::CThread()
{
    m_nIndex = m_nRef++;

    m_hThread = NULL;
    m_dwThreadId = 0;
}

CThread::~CThread()
{
    m_nRef--;
}

//////////////////////////////////////////////////////////////////////
// Implementation
//////////////////////////////////////////////////////////////////////
void CThread::Create()
{
    m_hThread = ::CreateThread(0, 0, ThreadProc, this, 0, &m_dwThreadId);
}

void CThread::Stop()
{
    while (::WaitForSingleObject(m_hThread, 0) != WAIT_OBJECT_0)
        Sleep(50);

    CloseHandle(m_hThread);
    m_hThread = NULL;
    m_dwThreadId = 0;
}

DWORD WINAPI CThread::ThreadProc(LPVOID lpParam)
{
    CThread *pThread = (CThread *)lpParam;
    ::ExitThread(pThread->OnThreadProc());
    return 0;
}

  

이제 객체 스레드의 선언과 정의 부분을 구현하였고, 이 기반 클래스(Base Class)로부터 상속받아 예제 프로그램을 작성해 보도록 하겠습니다. 다음의 예제 프로그램은 파일을 삭제하는 객체 스레드입니다.

class CDeleteFileThread : pulbic CThread
{
public:
    CDeleteFileThread();
    virtual ~CDeleteFileThread();

    void SetPath(LPCTSTR);

protected:
    virtual DWORD OnThreadProc();
   
protected:
    TCHAR m_szPath[MAX_PATH];
};

CDeleteFileThread::CDeleteFileThread()
{
    memset(m_szPath, 0, MAX_PATH*sizeof(TCHAR));
}

CDeleteFileThread::~CDeleteFileThread()
{
}

void CDeleteFileThread::SetPath(LPCTSTR lpcszPath)
{
    _tcscpy(m_szPath, lpcszPath);
}

DWORD CDeleteFileThread::OnThreadProc()
{
    SHFILEOPSTRUCT shfo = {0};
    shfo.wFunc = FO_DELETE;
    shfo.pFrom = m_szPath;
    SHFileOperation(&shfo);

    return 0;
}

  

Posted by Y2K
,