| マルチスレッドの生成 |
UINT ControlFunction( LPVOID pParam );制御関数を作成する前に、ここでは制御関数の引数として使用するクラスCUKWorkerParamを作成する。 このクラスはデータメンバとしてCListBoxへのポインタと、CString型の文字列を持つ。 今回作成するプロジェクトではスレッド内でリストボックスへ文字列を追加するために、これらの情報が必要となる。 あとはデータメンバに値を設定するSetParam関数と、それらの値を個別に取得するための関数を定義すればよい。 以下にCUKWorkerParamクラスの定義を示しておく。
// ワーカースレッド制御関数の引数として使用するクラス
class CUKWorkerParam
{
public:
CUKWorkerParam() {};
void SetParam( CListBox* pListBox, CString strString )
{
m_pListBox = pListBox;
m_strString = strString;
}
CListBox* GetListBox() { return m_pListBox; }
CString GetString() { return m_strString; }
private:
CListBox* m_pListBox; // リストボックスへのポインタ
CString m_strString; // リストボックスへ追加する文字列
};
CUKWorkerParamクラスを定義したら、いよいよ制御関数WorkerThreadを定義する。
定義の内容については以下に示すとおりである。まず引数pParamをCUKWorkerParam型のポインタに変換し、
ここからリストボックスへのポインタと文字列を取得する。
そしてスレッド内ではリストボックスへ文字列を5回追加し、処理を終了する。
// ワーカースレッド制御関数
UINT WorkerThread( LPVOID pParam )
{
CUKWorkerParam* pWorker = (CUKWorkerParam*)pParam;
CListBox* pListBox = pWorker->GetListBox();
CString strString = pWorker->GetString();
for( int i = 0; i < 5; i++ )
pListBox->AddString(strString);
return 0;
};
class CUKMultiThreadDlg : public CDialog
{
……
private:
CUKWorkerParam m_Worker1;
CUKWorkerParam m_Worker2;
CUKWorkerParam m_Worker3;
CUKWorkerParam m_Worker4;
};
ヘッダーを編集したら、次にソースを修正する。CUKMultiThreadDlg.cppを開き、OnInitDialog関数を次のようにする。
BOOL CUKMultiThreadDlg::OnInitDialog()
{
CDialog::OnInitDialog();
……
// TODO: 特別な初期化を行う時はこの場所に追加してください。
m_Worker1.SetParam(&m_List1, "1");
m_Worker2.SetParam(&m_List1, "2");
m_Worker3.SetParam(&m_List1, "3");
m_Worker4.SetParam(&m_List1, "4");
AfxBeginThread(WorkerThread, &m_Worker1);
AfxBeginThread(WorkerThread, &m_Worker2);
AfxBeginThread(WorkerThread, &m_Worker3);
AfxBeginThread(WorkerThread, &m_Worker4);
return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}
4つのCUKWorkerParamオブジェクトにパラメータを設定した後、AfxBeginThread関数を使ってスレッドを起動している。
これでプロジェクトをビルドし、実行してみる。そうすると4つのスレッドはそれぞれ数字(文字列)の1、2、3、4のうち、
SetParam関数で指定されたいずれかの値をリストボックスへ追加する。
注目してほしいのは、それぞれが並行して処理をおこなっているため、
あるスレッドで5回文字列を追加し終わる前に他のスレッドの処理が割り込み、文字列を追加しているということだ。
そしてCPUの使用率などによっては実行するたびにこの順番が入れ替わることもありうる。
(ただし、次のスレッドが走り出す前に前のスレッドの処理が終了した場合にはこの限りではない)