トップ回答者
複数のスレッドを同時に起動する方法はないでしょうか

質問
回答
-
イメージ的にはWaitForSingleObject(では出来ないとは思いますが)でシグナル待ちしているスレッドを複数作成し、1つのオブジェクトでイベント待ちしている全てのスレッドを同時起動するようなことを考えております。
間違っていましたらすみません。複数スレッド処理の初めで WaitForSingleObject 関数で指定オブジェクトがシグナル状態になるのを待つのでは駄目なのでしょうか?例えば下記のコードのように
#include <windows.h> HANDLE hEvent; DWORD WINAPI ThreadFunc1(LPVOID p) { WaitForSingleObject(hEvent, INFINITE); OutputDebugString(TEXT("1\r\n")); PostMessage((HWND)p, WM_APP + 1, 0, 0); ExitThread(0); } DWORD WINAPI ThreadFunc2(LPVOID p) { WaitForSingleObject(hEvent, INFINITE); OutputDebugString(TEXT("2\r\n")); PostMessage((HWND)p, WM_APP + 2, 0, 0); ExitThread(0); } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HANDLE hThread1; static HANDLE hThread2; switch (msg) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), TEXT("複数スレッド起動"), WS_VISIBLE | WS_CHILD, 10, 10, 256, 32, hWnd, (HMENU)IDOK, ((LPCREATESTRUCT)lParam)->hInstance, 0); break; case WM_COMMAND: if (LOWORD(wParam) == IDOK) { if (hEvent) { CloseHandle(hEvent); hEvent = 0; } hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("TEST")); DWORD dwParam; hThread1 = CreateThread(0, 0, ThreadFunc1, (LPVOID)hWnd, 0, &dwParam); hThread2 = CreateThread(0, 0, ThreadFunc2, (LPVOID)hWnd, 0, &dwParam); Sleep(1000); SetEvent(hEvent); // 同時実行 } break; case WM_APP + 1: if (hThread1) { WaitForSingleObject(hThread1, INFINITE); CloseHandle(hThread1); hThread1 = 0; } break; case WM_APP + 2: if (hThread2) { WaitForSingleObject(hThread2, INFINITE); CloseHandle(hThread2); hThread2 = 0; } break; case WM_DESTROY: if (hEvent) { CloseHandle(hEvent); hEvent = 0; } PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } // WinMain は省略
- 編集済み kenjinoteMVP 2018年7月9日 9:38
- 回答としてマーク mt 2018年7月9日 23:22
すべての返信
-
イメージ的にはWaitForSingleObject(では出来ないとは思いますが)でシグナル待ちしているスレッドを複数作成し、1つのオブジェクトでイベント待ちしている全てのスレッドを同時起動するようなことを考えております。
間違っていましたらすみません。複数スレッド処理の初めで WaitForSingleObject 関数で指定オブジェクトがシグナル状態になるのを待つのでは駄目なのでしょうか?例えば下記のコードのように
#include <windows.h> HANDLE hEvent; DWORD WINAPI ThreadFunc1(LPVOID p) { WaitForSingleObject(hEvent, INFINITE); OutputDebugString(TEXT("1\r\n")); PostMessage((HWND)p, WM_APP + 1, 0, 0); ExitThread(0); } DWORD WINAPI ThreadFunc2(LPVOID p) { WaitForSingleObject(hEvent, INFINITE); OutputDebugString(TEXT("2\r\n")); PostMessage((HWND)p, WM_APP + 2, 0, 0); ExitThread(0); } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static HANDLE hThread1; static HANDLE hThread2; switch (msg) { case WM_CREATE: CreateWindow(TEXT("BUTTON"), TEXT("複数スレッド起動"), WS_VISIBLE | WS_CHILD, 10, 10, 256, 32, hWnd, (HMENU)IDOK, ((LPCREATESTRUCT)lParam)->hInstance, 0); break; case WM_COMMAND: if (LOWORD(wParam) == IDOK) { if (hEvent) { CloseHandle(hEvent); hEvent = 0; } hEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("TEST")); DWORD dwParam; hThread1 = CreateThread(0, 0, ThreadFunc1, (LPVOID)hWnd, 0, &dwParam); hThread2 = CreateThread(0, 0, ThreadFunc2, (LPVOID)hWnd, 0, &dwParam); Sleep(1000); SetEvent(hEvent); // 同時実行 } break; case WM_APP + 1: if (hThread1) { WaitForSingleObject(hThread1, INFINITE); CloseHandle(hThread1); hThread1 = 0; } break; case WM_APP + 2: if (hThread2) { WaitForSingleObject(hThread2, INFINITE); CloseHandle(hThread2); hThread2 = 0; } break; case WM_DESTROY: if (hEvent) { CloseHandle(hEvent); hEvent = 0; } PostQuitMessage(0); break; default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; } // WinMain は省略
- 編集済み kenjinoteMVP 2018年7月9日 9:38
- 回答としてマーク mt 2018年7月9日 23:22
-
補足すると、CreateEvent()の第2引数bManualResetをtrueに設定すると、ResetEvent()を呼ぶまでシグナル状態を維持するため、そのタイミングで待ち受けていたWaitForSingleObject系は全て処理を継続できます。
逆にbManualResetをfalseに設定すると、ある1スレッドのWaitForSingleObject系だけが処理を継続し、残りのスレッドは待機し続けます。この機能を使うことで、質問文「複数作成したスレッドを、1つのオブジェクトで同時に起動する」を実現できます。