|
동일한 Thread가 여러개 있는 경우 Thread처리부를 Class화 하는 것이 사용하기 좋습니다.
또한 VCL의 Method와 property를 사용할 경우 반드시 main VCL thread에서 처리해
줘야 프로그램이 죽지않고 원활히 동작합니다(동기화 부분은 Thread에서 무척 중요하며
Windows에 있는 4개의 동기화 객체에 대해 틈틈히 공부해 두면 좋습니다. ^_^;;)
이러한 작업은 C++ Builder Class에 이미있으며, 그 Class 이름은 TThread입니다.
TThread를 상속받아 Execute() Method를 처리해 주면 별 문제 없이 돌아갈 겁니다.
참고로 아래 프로그램은 님의 프로그램을 기본으로 만들었으면 TCheckBox 부분은
처리에서 제외했습니다.
행복한 하루 되시길......
----------------------------------------------------------------------------------------
*** main_src.H ***
//---------------------------------------------------------------------------
#ifndef main_srcH
#define main_srcH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ComCtrls.hpp>
//---------------------------------------------------------------------------
class TMyThread : public TThread
{
private:
protected:
void __fastcall Execute();
public:
TProgressBar *ppbBar;
TStaticText *pstLabel;
int nDelay;
__fastcall TMyThread(bool CreateSuspended);
void __fastcall PutProgress( void );
};
//---------------------------------------------------------------------------
class Tform_main : public TForm
{
__published:
TGroupBox *GroupBox1;
TCheckBox *chkbox_com1;
TCheckBox *chkbox_com2;
TCheckBox *chkbox_com3;
TCheckBox *chkbox_com4;
TCheckBox *chkbox_com5;
TCheckBox *chkbox_com6;
TCheckBox *chkbox_com7;
TCheckBox *chkbox_com8;
TProgressBar *ProgressBar1;
TProgressBar *ProgressBar2;
TProgressBar *ProgressBar3;
TProgressBar *ProgressBar4;
TProgressBar *ProgressBar5;
TProgressBar *ProgressBar6;
TProgressBar *ProgressBar7;
TProgressBar *ProgressBar8;
TStaticText *st_com1;
TStaticText *st_com2;
TStaticText *st_com3;
TStaticText *st_com4;
TStaticText *st_com5;
TStaticText *st_com6;
TStaticText *st_com7;
TStaticText *st_com8;
TButton *btn_com1;
TButton *btn_com2;
TButton *btn_com3;
TButton *btn_com4;
TButton *btn_com5;
TButton *btn_com6;
TButton *btn_com7;
TButton *btn_com8;
void __fastcall btn_com1Click(TObject *Sender);
private:
public:
TMyThread *pThread[8];
__fastcall Tform_main(TComponent* Owner);
__fastcall ~Tform_main( void );
};
//---------------------------------------------------------------------------
extern PACKAGE Tform_main *form_main;
//---------------------------------------------------------------------------
#endif
*** main_src.cpp ***
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "main_src.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Tform_main *form_main;
//---------------------------------------------------------------------------
__fastcall TMyThread::TMyThread(bool CreateSuspended) : TThread(CreateSuspended)
{
ppbBar = NULL;
pstLabel = NULL;
nDelay = 100;
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
while( !Terminated ) {
if( ppbBar != NULL ) {
Synchronize( PutProgress );
if( (nDelay < 0) | (nDelay > 10000) ) {
nDelay = 100;
}
Sleep( nDelay );
}
else {
Sleep( 100 );
}
}
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::PutProgress( void )
{
if( ppbBar != NULL ) {
if( ppbBar->Position < ppbBar->Max ) {
ppbBar->Position = ppbBar->Position + 1;
}
else if( pstLabel != NULL ) {
pstLabel->Caption = "완료됨";
// 아래는 조금 특이하게 작성됐습니다. Thread에서 자신을 Suspend 시키다니... ㅋㅋㅋ
// 언제 Suspend되는지 직접 확인해 보세요.
Suspend();
}
}
}
//---------------------------------------------------------------------------
__fastcall Tform_main::Tform_main(TComponent* Owner) : TForm(Owner)
{
for(int nI = 0; nI < sizeof(pThread) / sizeof(pThread[0]); nI++ ) {
pThread[nI] = new TMyThread( true );
}
pThread[0]->ppbBar = ProgressBar1; pThread[0]->pstLabel = st_com1; pThread[0]->nDelay = 50;
pThread[1]->ppbBar = ProgressBar2; pThread[1]->pstLabel = st_com2; pThread[1]->nDelay = 100;
pThread[2]->ppbBar = ProgressBar3; pThread[2]->pstLabel = st_com3; pThread[2]->nDelay = 150;
pThread[3]->ppbBar = ProgressBar4; pThread[3]->pstLabel = st_com4; pThread[3]->nDelay = 200;
pThread[4]->ppbBar = ProgressBar5; pThread[4]->pstLabel = st_com5; pThread[4]->nDelay = 250;
pThread[5]->ppbBar = ProgressBar6; pThread[5]->pstLabel = st_com6; pThread[5]->nDelay = 300;
pThread[6]->ppbBar = ProgressBar7; pThread[6]->pstLabel = st_com7; pThread[6]->nDelay = 200;
pThread[7]->ppbBar = ProgressBar8; pThread[7]->pstLabel = st_com8; pThread[7]->nDelay = 150;
}
//---------------------------------------------------------------------------
__fastcall Tform_main::~Tform_main( void )
{
for(int nI = 0; nI < sizeof(pThread) / sizeof(pThread[0]); nI++ ) {
if( pThread[nI] != NULL ) {
if( pThread[nI]->Suspended ) {
pThread[nI]->Resume();
}
pThread[nI]->Terminate();
pThread[nI]->WaitFor();
}
}
}
//---------------------------------------------------------------------------
void __fastcall Tform_main::btn_com1Click(TObject *Sender)
{
AnsiString asName = Sender->ClassName();
if( asName == "TButton" ) {
TButton *pbtn = (TButton *) Sender;
if( (pbtn->Tag >= 0) & (pbtn->Tag <= sizeof(pThread) / sizeof(pThread[0])) ) {
TMyThread *pMyThread = pThread[pbtn->Tag];
if( pMyThread != NULL ) {
if( pMyThread->Suspended ) {
pMyThread->ppbBar->Position = pMyThread->ppbBar->Min;
pMyThread->pstLabel->Caption = "시작됨";
pMyThread->Resume();
}
else {
pMyThread->Suspend();
pMyThread->pstLabel->Caption = "취소됨";
}
}
}
}
}
//---------------------------------------------------------------------------
*** main_src.dfm ***
object form_main: Tform_main
Left = 307
Top = 256
Width = 656
Height = 350
Caption = 'Downloader example'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object GroupBox1: TGroupBox
Left = 8
Top = 8
Width = 633
Height = 301
Caption = 'Progress Display'
TabOrder = 0
object chkbox_com1: TCheckBox
Left = 24
Top = 32
Width = 55
Height = 17
Caption = 'COM 1'
TabOrder = 0
end
object chkbox_com2: TCheckBox
Left = 24
Top = 64
Width = 55
Height = 17
Caption = 'COM 2'
TabOrder = 1
end
object chkbox_com3: TCheckBox
Left = 24
Top = 96
Width = 55
Height = 17
Caption = 'COM 3'
TabOrder = 2
end
object chkbox_com4: TCheckBox
Left = 24
Top = 128
Width = 55
Height = 17
Caption = 'COM 4'
TabOrder = 3
end
object chkbox_com5: TCheckBox
Left = 24
Top = 160
Width = 55
Height = 17
Caption = 'COM 5'
TabOrder = 4
end
object chkbox_com6: TCheckBox
Left = 24
Top = 192
Width = 55
Height = 17
Caption = 'COM 6'
TabOrder = 5
end
object chkbox_com7: TCheckBox
Left = 24
Top = 224
Width = 55
Height = 17
Caption = 'COM 7'
TabOrder = 6
end
object chkbox_com8: TCheckBox
Left = 24
Top = 256
Width = 55
Height = 17
Caption = 'COM 8'
TabOrder = 7
end
object ProgressBar1: TProgressBar
Left = 88
Top = 32
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 8
end
object ProgressBar2: TProgressBar
Left = 88
Top = 64
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 9
end
object ProgressBar3: TProgressBar
Left = 88
Top = 96
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 10
end
object ProgressBar4: TProgressBar
Left = 88
Top = 128
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 11
end
object ProgressBar5: TProgressBar
Left = 88
Top = 160
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 12
end
object ProgressBar6: TProgressBar
Left = 88
Top = 192
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 13
end
object ProgressBar7: TProgressBar
Left = 88
Top = 224
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 14
end
object ProgressBar8: TProgressBar
Left = 88
Top = 256
Width = 361
Height = 22
Min = 0
Max = 100
TabOrder = 15
end
object st_com1: TStaticText
Left = 551
Top = 32
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 16
end
object st_com2: TStaticText
Left = 551
Top = 64
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 17
end
object st_com3: TStaticText
Left = 551
Top = 96
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 18
end
object st_com4: TStaticText
Left = 551
Top = 128
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 19
end
object st_com5: TStaticText
Left = 551
Top = 160
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 20
end
object st_com6: TStaticText
Left = 551
Top = 192
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 21
end
object st_com7: TStaticText
Left = 551
Top = 224
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 22
end
object st_com8: TStaticText
Left = 551
Top = 256
Width = 59
Height = 17
Alignment = taCenter
AutoSize = False
BorderStyle = sbsSunken
Font.Charset = ANSI_CHARSET
Font.Color = clBlue
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
TabOrder = 23
end
object btn_com1: TButton
Left = 464
Top = 32
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 24
OnClick = btn_com1Click
end
object btn_com2: TButton
Tag = 1
Left = 464
Top = 64
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 25
OnClick = btn_com1Click
end
object btn_com3: TButton
Tag = 2
Left = 464
Top = 96
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 26
OnClick = btn_com1Click
end
object btn_com4: TButton
Tag = 3
Left = 464
Top = 128
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 27
OnClick = btn_com1Click
end
object btn_com5: TButton
Tag = 4
Left = 464
Top = 160
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 28
OnClick = btn_com1Click
end
object btn_com6: TButton
Tag = 5
Left = 464
Top = 192
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 29
OnClick = btn_com1Click
end
object btn_com7: TButton
Tag = 6
Left = 464
Top = 224
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 30
OnClick = btn_com1Click
end
object btn_com8: TButton
Tag = 7
Left = 464
Top = 256
Width = 75
Height = 25
Caption = 'Download'
TabOrder = 31
OnClick = btn_com1Click
end
end
end
---------------------------------------------------------------------
초보 빌더 유저 님이 쓰신 글 :
: 안녕하세요..
: 간단히 멀티 스레드 프로그래밍 테스트 프로그램 짜고 있는데요..
:
: --> 소스를 보시고 직접 돌려 보셔서 지적해 주시면 감사하겠습니다.
:
: 폼 생성시 CreateThread로 스레드 헨들을 생성하고..(8개의 스레드 생성)
: 버튼을 누르면 그것들이 스레드를 Resume시키구요..
: ThreadFunc에서 하는 일은 ProgressBar의 position을 2씩 증가 시키는 것인데요..
: 각 스레드를 생성하면 한번만 실행되고 그 다음에 멈추는데.. 이해가 되지 않네요..
: Suspend를 명시적으로 해주기 전에는 100까지 계속 증가 되어야 할것 같은데..
:
: 답변을 주시면 정말 감사하겠습니다.
:
:
:
:
|