CPUのクロック数も伸び悩む中、今度はマルチコア化が世の流れです。
せっかくCore2Duoなんかを使っててもシングルスレッドでは50%しか使えてませんよ。
というわけで、今回はマルチスレッドを試してみます。
初めてのマルチスレッドなのでBuilderが提供するTThreadクラスを利用してシンプルなモノを作ります。
←こんなフォームを作った。
TMemoは表示用、スレッド1, 2ボタンはそれぞれ実行させる用。
「同時実行」ボタンが今回のマルチスレッドです。
<Unit1.h>
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
// スレッド1のクラス
class CThread1 : public TThread
{
public: // パブリック宣言で
__fastcall CThread1(bool CreateSuspended); // TThreadからコンストラクタと
void __fastcall Execute(void); // 実行関数を忘れずに継承
};
//---------------------------------------------------------------------------
// スレッド2のクラス
class CThread2 : public TThread
{
public: // パブリック宣言で
__fastcall CThread2(bool CreateSuspended); // TThreadからコンストラクタと
void __fastcall Execute(void); // 実行関数を忘れずに継承
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE 管理のコンポーネント
TMemo *Memo1;
TButton *Th1Btn;
TButton *Th2Btn;
TButton *BothBtn;
void __fastcall Th1BtnClick(TObject *Sender);
void __fastcall Th2BtnClick(TObject *Sender);
void __fastcall BothBtnClick(TObject *Sender);
private: // ユーザー宣言
public: // ユーザー宣言
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
<Unit1.cpp>
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
// スレッド1実行
void __fastcall TForm1::Th1BtnClick(TObject *Sender)
{
// スレッド1を作成
CThread1 *th1 = new CThread1(true); // CreateSuspended = trueの場合
// スレッドは停止した状態で作成されます
th1->Resume(); // Resume()で停止スレッドを再開します
}
//---------------------------------------------------------------------------
// スレッド2実行
void __fastcall TForm1::Th2BtnClick(TObject *Sender)
{
// スレッド2を作成
CThread2 *th2 = new CThread2(true); // CreateSuspended = trueの場合
// スレッドは停止した状態で作成されます
th2->Resume(); // Resume()で停止スレッドを再開します
}
//---------------------------------------------------------------------------
// スレッド1と2同時実行
void __fastcall TForm1::BothBtnClick(TObject *Sender)
{
CThread1 *th1 = new CThread1(true); // スレッド1と2を停止状態で作成して
CThread2 *th2 = new CThread2(true);
th1->Resume(); // 今度は同時に実行!
th2->Resume();
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// スレッド1コンストラクタ
__fastcall CThread1::CThread1(bool CreateSuspended) : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
// スレッド1実行内容
void __fastcall CThread1::Execute(void)
{
// Memo1に1〜10まで表示するだけ
for( int i=0; i<10; i++ ){
Form1->Memo1->Lines->Add("スレッド1--> " + IntToStr(i));
}
}
//---------------------------------------------------------------------------
// スレッド2コンストラクタ
__fastcall CThread2::CThread2(bool CreateSuspended) : TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
// スレッド2実行内容
void __fastcall CThread2::Execute(void)
{
// Memo1に1〜10まで表示するだけ
for( int i=0; i<10; i++ ){
Form1->Memo1->Lines->Add("スレッド2--> " + IntToStr(i));
}
}
//---------------------------------------------------------------------------
どうでしょう?
「同時実行」ボタンを押すと、スレッド1とスレッド2が入り乱れてMemo1に追加してってます。
もちろん、スレッド3,4...と増やしても問題ありません。
ちなみに、TThreadクラスを使うには、最低限コンストラクタとExecuteを継承する必要があります。
今回は、1から10まで数える処理をそれぞれのスレッド内で実行しているだけですが
スレッドを使う利点としては、メニューの表示と重い処理を切り分けたり
別々のスレッドで重い処理を分担して演算したり...という使い方があります。