もくじ
やりたいこと
最近のC++では、マルチスレッドで処理を行うときに、処理の中身をラムダ式で書けたりするらしい。試したい。
サンプルプログラム
#include <thread>
#include "framework.h"
#include "WindowsProject1.h"
#include "resource.h"
// グローバル変数:
HINSTANCE hInst; // 現在のインターフェイス
// このコード モジュールに含まれる関数の宣言を転送します:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
hInst = hInstance;
DialogBox(hInst, L"MyTestDlgBase_Main", NULL, (DLGPROC)MyDlgProc);
return (int)0;
}
// スレッド終了フラグ
int threadStop = !0;
// スレッドAの処理
void ThreadA()
{
OutputDebugString(L"+ スレッドA開始\r\n");
while (!threadStop)
{
OutputDebugString(L" スレッドA実行中...\r\n");
Sleep(500);
}
OutputDebugString(L"- スレッドA終了\r\n");
}
// 参考
// スレッド終了時にはjoin()で待たないといけないのはここを見て気づいた
// https://qiita.com/kaoru/items/7de0399b11f83241687c
// ラムダでの書き方
// https://qiita.com/termoshtt/items/d3cb7fe226cdd498d2ef
BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
static std::thread th_a;
static std::thread th_b;
switch (msg) {
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDOK:
EndDialog(hDlg, IDOK);
return TRUE;
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
return TRUE;
case IDC_BUTTON1:
if (threadStop != 0)
{
// スレッドA,Bの終了フラグをクリア
threadStop = 0;
// スレッドA開始
th_a = std::thread(ThreadA);
// スレッドB開始
int param = 0;
th_b = std::thread([¶m]{
OutputDebugString(L"+ スレッドB開始\r\n");
while (!threadStop)
{
OutputDebugString(L" スレッドB実行中...\r\n");
Sleep(1000);
}
OutputDebugString(L"- スレッドB終了\r\n");
});
}
else
{
// スレッドA,Bの終了フラグをON(スレッドを終わらせる)
threadStop = !0;
// スレッド終了時にはjoinで終わるのを待たないと、異常終了してしまう(Abort)
th_a.join();
th_b.join();
}
break;
}
return FALSE;
case WM_CLOSE:
threadStop = !0;
th_a.join();
th_b.join();
break;
}
return FALSE;
}
引っかかった点
スレッドが終わりきってないときにexeが終了すると、エラーが起きてしまう。
なので、スレッドが終わるまで待ってからプログラム終了するようにする。
スレッドが終わるのをまつため、th_a.join();
を使ってスレッドが終わるまで待つ。
std::thread th_a = std::thread(ThreadA);と書くと、その時点からスレッドが走り出す
std::thread
のobjectだけ先に作っておいて、後で好きな時にstartさせたかったが、std::thread th_a = std::thread(ThreadA);
とかくと、その時点からすぐにスレッドが走り出してしまう。
まずはstd::thread th_a;
で宣言だけしておいて、スタートさせたいところでth_a = std::thread(ThreadA);
をすればOK。