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
[677] 지정 함수를 쓰레드에 실어서 실행시키는 클래스
김태선 [cppbuilder] 8796 읽음    2007-07-20 18:45
장성호님과 여러분이 아래아래에 있는 제 팁 속의 질문에 대한
정답을 말하라고 해서 그것에 대한 답변으로 올립니다.

제 질문의 핵심은 쓰레드를 이동한 동시 실행 기법인데,
사실 머.. 신선한 주제는 아닙니다만, 의외로 실전에서 답답하게 코딩된 경우를 많이 봅니다.
함수가 실행되는 동안 화면이 꼼짝하지 않는 상황을 벗어날때
그외 다중으로 루틴을 실행할때 필요한 기법입니다.

이 클래스는 실전에 상당한 가치가 있으리라 생각됩니다.

//---------------------------------------------------------------------------

화면에 버턴을 올려 놓고 더블클릭해서 코딩을 합니다.
그런데, 이벤트 함수내에서 무엇을 처리하는 시간이 깁니다.
그러면 화면은 꼼짝을 안하죠... 뭘 클릭해도 가만히 있고...
이렇게 시간이 걸리는 루틴은 쓰레드로 만드는 것이 정석입니다.

하지만 이렇게 쓰레드로 만들고 있자니 좀 번거러운 면이 있습니다.
이것을 일반화 시킬 수는 없을까?
그래서 만든 것이 아래 클래스입니다.

시간이 오래 걸리는 함수를 이 클래스를 생성할때 지정하면
그 함수를 쓰레드에서 실행하고 즉시 리턴됩니다.
그러면 바로 또 다른 화면 조작을 할수 있습니다.
그 함수의 실행이 종료되면 자동으로 쓰레드도 종료됩니다.

아래는 소스입니다.
아주 간단하죠...
일단 TNotifyEvent 형 함수만 지정할 수 있게 했는데,
다른 형의 함수는 소스를 살짝꿍 수정하면 될 것입니다.

//---------------------------------------------------------------------------
// 지정 함수를 쓰레드에서 실행시키는 클래스
//        Sender는 호출자 구분이 필요할시 쓰기 위함.
//
//
// Written by 김태성

class TRunThread : public TThread
{
private:
    TNotifyEvent     OnEvent;
    TObject*         Sender;

public:
    __fastcall TRunThread(TNotifyEvent event, TObject* sender)
        : TThread(false)
    {
        FreeOnTerminate = true;
        OnEvent = event;
        Sender = sender;
    }
    void __fastcall Execute()
    {
        OnEvent(Sender);
    }
};
//---------------------------------------------------------------------------
// 요건  쓰레드에 실어서 실행할 함수 입니다.

void __fastcall TForm1::TestFunc(TObject *Sender)
{
    // 엄청 시간이 걸리는 루틴.
    int  k;
    for(int c = 0; c < 199999999; c++)
    {
        k = c;
        k++;
        c = k;
        c--;
    }
    Caption = k;
    Button3->Enabled = true;
}
//---------------------------------------------------------------------------
// 쓰레드를 생성한후 쓰레드에서 함수를 실행한후 즉시 리턴해 프로그램 실행을 계속한다.

void __fastcall TForm1::Button3Click(TObject *Sender)
{
    Button3->Enabled = false;
    TRunThread*  thread = new TRunThread(&TestFunc, Sender);
    thread;
}
//---------------------------------------------------------------------------







다음은 사용하기 좀 더 간편하게 스택에 생성할 수 있는 클래스 버전입니다.

//---------------------------------------------------------------------------
// 지정 함수를 쓰레드에서 실행시키는 클래스 (스택생성 가능 버전)
//        Sender는 호출자 구분이 필요할시 쓰기 위함.
//
//
// Written by 김태성

class CRunThread
{
    class TRunThread : public TThread
    {
    private:
        TNotifyEvent     OnEvent;
        TObject*         Sender;

    public:
        __fastcall TRunThread(TNotifyEvent event, TObject* sender)
            : TThread(false)
        {
            FreeOnTerminate = true;
            OnEvent = event;
            Sender = sender;
        }
        void __fastcall Execute()
        {
            OnEvent(Sender);
        }
    };
public:
    CRunThread(TNotifyEvent event, TObject* sender)
    {
        TRunThread*  thread = new TRunThread(event, sender);
    }
};
//---------------------------------------------------------------------------
// 요건  쓰레드에 실어서 실행할 함수 입니다.

void __fastcall TForm1::TestFunc(TObject *Sender)
{
    // 엄청 시간이 걸리는 루틴.
    int  k;
    for(int c = 0; c < 199999999; c++)
    {
        k = c;
        k++;
        c = k;
        c--;
    }
    Caption = k;
    Button1->Enabled = true;
}
//---------------------------------------------------------------------------
// 쓰레드를 생성한후 쓰레드에서 함수를 실행한후 즉시 리턴해 프로그램 실행을 계속한다.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    Button1->Enabled = false;
    CRunThread  thread(&TestFunc, Sender);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Caption = "하하하";
}
//---------------------------------------------------------------------------


끝.
김태선 [cppbuilder]   2007-07-20 19:00 X
CPU가 엄청 빠른 분은
TestFunc
함수가 더 시간이 걸리게 조금 손보시기 바랍니다.

김권영 [devilica]   2007-07-21 09:09 X
정말 중요한 테크닉이네요.. 잘 봤습니다.~
김태선 [cppbuilder]   2007-07-23 10:35 X
TestFunc내에서 VCL을 사용하고 현재 실행중인 VCL 동작과 부딪칠 경우는 TestFunc 함수를 Synchonize 를 통해 호출해야 합니다. 사실 이 경우는 멀티 쓰레드로 동작하는 것이 아니므로, Synchonize 를 쓰지 말고 TestFunc 함수 내에서 VCL을 알맞게 사용하도록 만드는 것이 좋습니다.

+ -

관련 글 리스트
677 지정 함수를 쓰레드에 실어서 실행시키는 클래스 김태선 8796 2007/07/20
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.