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

C++빌더 Q&A
C++Builder Programming Q&A
[28114] Re:빌더로 멀티스레드 프로그램 짜던중 질문 입니다.
김용수 [] 1505 읽음    2003-12-04 21:39
동일한 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까지 계속 증가 되어야 할것 같은데..
:
: 답변을 주시면 정말 감사하겠습니다.
:
:
:
:

+ -

관련 글 리스트
28109 빌더로 멀티스레드 프로그램 짜던중 질문 입니다. 초보 빌더 유저 1153 2003/12/04
34121     Re:빌더로 멀티스레드 프로그램 짜던중 질문 입니다. 강영준 946 2003/12/04
28114     Re:빌더로 멀티스레드 프로그램 짜던중 질문 입니다. 김용수 1505 2003/12/04
28110     Re:빌더로 멀티스레드 프로그램 짜던중 질문 입니다. 임문환.실업자 1287 2003/12/04
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.