LoginSignup
1
1

More than 5 years have passed since last update.

c++ builder / TThread > スレッドが終了時にソフトを終了する実装

Last updated at Posted at 2016-04-26
動作確認
C++ Builder XE4

メインスレッドがエラーで終了した時にソフトを終了させる実装を考えた。

Main.cpp

Main.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    m_terminate = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    String msg = DateTimeToStr(Now());
    OutputDebugString(msg.c_str());

    if (m_terminate) {
        Close();
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    m_thr_main = new TThreadMain(/* CreateSuspend=*/false);
}
//---------------------------------------------------------------------------

__fastcall TForm1::~TForm1()
{
    if (m_thr_main != NULL) {
        m_thr_main->Terminate();
        for(int idx=0; idx<5; idx++) {
            Sleep(200);
            Application->ProcessMessages();
        }
    }
}

void __fastcall TForm1::SetTerminate()
{
    m_terminate = true;
}

Main.h

Main.h
//---------------------------------------------------------------------------

#ifndef MainH
#define MainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include "ThreadMain.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TTimer *Timer1;
    void __fastcall Timer1Timer(TObject *Sender);
    void __fastcall FormShow(TObject *Sender);
private:    // ユーザー宣言
    bool m_terminate;
    TThreadMain *m_thr_main;
public:     // ユーザー宣言
    void __fastcall SetTerminate();

    __fastcall TForm1(TComponent* Owner);
    __fastcall ~TForm1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

ThreadMain.cpp

ThreadMain.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "ThreadMain.h"
#include "Main.h"

#pragma package(smart_init)
//---------------------------------------------------------------------------

//   重要: VCL におけるオブジェクトのメソッドとプロパティは、Synchronize を使って
//   呼び出されるメソッドでのみ使用できます。たとえば、次のようになります。
//
//      Synchronize(&UpdateCaption);
//
//   ここで、UpdateCaption は 次のようなコードになります。
//
//      void __fastcall TThreadMain::UpdateCaption()
//      {
//        Form1->Caption = "スレッドで更新されました";
//      }
//---------------------------------------------------------------------------

__fastcall TThreadMain::TThreadMain(bool CreateSuspended)
    : TThread(CreateSuspended)
{
    FreeOnTerminate = true;

}
//---------------------------------------------------------------------------
void __fastcall TThreadMain::Execute()
{
    for(int idx = 0; idx < 5; idx++) {
        Sleep(1000);
    }

    Form1->SetTerminate();

    String msg = L"finish Execute()";
    OutputDebugString(msg.c_str());
}
//---------------------------------------------------------------------------

ThreadMain.h

ThreadMain.h
//---------------------------------------------------------------------------

#ifndef ThreadMainH
#define ThreadMainH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
//---------------------------------------------------------------------------
class TThreadMain : public TThread
{
private:
protected:
    void __fastcall Execute();
public:
    __fastcall TThreadMain(bool CreateSuspended);
};
//---------------------------------------------------------------------------
#endif

スレッドがExecute()を抜ける時にForm1のSetTerminate()をコールするようにした。

スレッドがForm1に依存してしまう。
closureを使うのも手かもしれない。

スレッドが落ちた時にソフトを終了でなく、スレッドを再起動することもできそう。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1