[MFC]マルチスレッド1
マルチスレッド
[環境]
VS2008
WIN32コンソールアプリ(MFC共通ヘッダ追加)
スレッドとはCPU利用の単位のこと。
1つのプロセス(今回の例ではコンソールアプリ)の中に1つ以上のスレッドを持つ。
このスレッドが同一プロセス内で複数もって処理を行うことが
マルチスレッドとなる。
マルチスレッドの用法としては、規模の大きい計算などをメインの処理から分岐させ、
バックグラウンドで非同期に処理を行わせるイメージ。
(実際はちょっと意味合いは違う。イメージ。)
組込などのRTOSなどでも使われ方が多少違ってくると思う。
以下、簡単なスレッドの生成と、その流れをコードで。
スレッドの種類にはワーカースレッドとユーザーインターフェーススレッド
があるが、今回はワーカースレッドについて。
// スレッド関数
UINT ThreadFunc(LPVOID param)
{
printf("スレッド起動\n");
Sleep(1000);
printf("スレッド終了\n");
return 0;
}
// メイン処理
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
printf("メイン開始\n");
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
・・・中略
}
else
{
CWinThread *pThread = AfxBeginThread(ThreadFunc, NULL);
}
printf("メイン終了\n");
return nRetCode;
}
main からAfxBeginThread()関数を呼び、スレッドを生成している。
渡す引数は、実行するスレッド用の関数のポインタと、それに渡すパラメータ
を指定すればとりあえずOK。
AfxBeginThread はCWinThread 型のポインタを返すので、受け取る。
(今回は特に使用しない。)
今回はThreadFuncという作成したスレッド用関数と、その関数の引数となる
値だけを渡している。
(上記例は、スレッド用関数は引数が不要なのでNULLとしている。
第2引数はvoid型のポインタである必要があるので、実際に引数を
使用する際は、元の型にキャストするなどして使用する。)
スレッド関数で行っていることは、処理の突入/終了を表示することと、
その間に1秒間のスリープをしているだけである。
先に述べたように、メインの処理とは非同期で処理を行うので、上記コードを
実行すると次のような結果となる。
(処理速度によっては変わることもあると思う。)
[結果]
> メイン開始
> メイン終了
> スレッド起動
このように、非同期で処理が進むためというのと、メイン処理がシンプルすぎることも
あってか、メイン処理が終わってからやっとスレッドが起動している。
しかも、スレッド終了が呼ばれていない。
この時どうなるかというと、メインはすでに終了しているのにスレッドだけが動いている
ということで、メモリリークが発生する。
つまり、これに対応するには、メインが終了する前にスレッドの終了を
待つ必要がでてくる。
対応方法については次回 。