ミューテックスを使って、

実行するスレッドを一つに限定できます。

 

WaitForSingleObject関数で、

ミューテックスの所有権を受け取るまで、

実行を停止することができます。

 

〇プログラム例

注:連続してCreateThread関数を作成すると、

スレッドの実行は作成順とならない場合があります。

 

  1. #include <windows.h>
  2.  
  3. #define MUTEX_NAME TEXT("Mutex Object")
  4.  
  5. typedef struct _ThreadParam {
  6.     HWND owner;
  7.     int counter;
  8. } ThreadParam;
  9.  
  10. DWORD WINAPI ThreadFunc(LPVOID vdParam) {
  11.     ThreadParam* param;
  12.     HANDLE hMutex;
  13.  
  14.     param=((ThreadParam*)vdParam);
  15.     hMutex = CreateMutex(NULL, FALSE, MUTEX_NAME);
  16.  
  17.     while (param->counter < 1000) {
  18.         int i;
  19.         WaitForSingleObject(hMutex, INFINITE);
  20.         for (i = 0; i < 100; i++) {
  21.             param->counter += 1;
  22.             InvalidateRect(param->owner, NULL, TRUE);
  23.             Sleep(10);
  24.         }
  25.         ReleaseMutex(hMutex);
  26.     }
  27.     return 0;
  28.  
  29. }
  30.  
  31. static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  32. {
  33.     HDC hdc;
  34.     PAINTSTRUCT ps;
  35.     LPSTR str[64];
  36.     static HFONT hFont[2];
  37.  
  38.     static ThreadParam param1,param2,param3;
  39.     DWORD dwID;
  40.  
  41.     switch (uMsg)
  42.     {
  43.     case WM_DESTROY:
  44.         DeleteObject(hFont[0]);
  45.  
  46.         PostQuitMessage(0);
  47.         return 0;
  48.  
  49.     case WM_CREATE:
  50.         hFont[0] = CreateFont(
  51.             40, 0, 0, 0,
  52.             FW_NORMAL, FALSE, FALSE, FALSE,
  53.             SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS,
  54.             CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  55.             VARIABLE_PITCH | FF_DONTCARE, L"メイリオ"
  56.         );
  57.         ShowWindow(hWnd, SW_SHOW);
  58.  
  59.         param1.owner = param2.owner =param3.owner= hWnd;
  60.         param1.counter = param2.counter = param3.counter=0;
  61.         CreateThread(NULL, 0, ThreadFunc, (LPVOID)&param1, 0, &dwID);
  62.         CreateThread(NULL, 0, ThreadFunc, (LPVOID)&param2, 0, &dwID);
  63.         CreateThread(NULL, 0, ThreadFunc, (LPVOID)&param3, 0, &dwID);
  64.  
  65.         return 0;
  66.  
  67.     case WM_PAINT:
  68.         hdc = BeginPaint(hWnd, &ps);
  69.         SelectObject(hdc, hFont[0]);
  70.         SetTextColor(hdc, RGB(0, 0xFF, 0));
  71.  
  72.         wsprintf(str, TEXT("Thread1 count=%d"), param1.counter);
  73.         TextOut(hdc, 0, 0, str, lstrlen(str));
  74.  
  75.         wsprintf(str, TEXT("Thread2 count=%d"), param2.counter);
  76.         TextOut(hdc, 0, 30, str, lstrlen(str));
  77.  
  78.         wsprintf(str, TEXT("Thread3 count=%d"), param3.counter);
  79.         TextOut(hdc, 0, 60, str, lstrlen(str));
  80.  
  81.         EndPaint(hWnd, &ps);
  82.  
  83.         return 0;
  84.     }
  85.  
  86.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
  87.  
  88. }
  89.  
  90. int APIENTRY wWinMain(
  91.     _In_ HINSTANCE hInstance,
  92.     _In_opt_ HINSTANCE hPrevInstance,
  93.     _In_ LPWSTR ipCmdLine,
  94.     _In_ int nCmdShow
  95. ) {
  96.  
  97.     WNDCLASSEXW wcex;
  98.  
  99.     wcex.cbSize = sizeof(WNDCLASSEX);
  100.  
  101.     wcex.style = CS_HREDRAW | CS_VREDRAW;
  102.     wcex.lpfnWndProc = WndProc;
  103.     wcex.cbClsExtra = 0;
  104.     wcex.cbWndExtra = 0;
  105.     wcex.hInstance = hInstance;
  106.     wcex.hIcon = NULL;
  107.     wcex.hCursor = NULL;
  108.     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  109.     wcex.lpszMenuName = NULL;
  110.     wcex.lpszClassName = TEXT("TestWindow");
  111.     wcex.hIconSm = NULL;
  112.  
  113.     RegisterClassExW(&wcex);
  114.  
  115.     HWND hWnd = CreateWindowEx(0UL, TEXT("TestWindow"), TEXT("日本"), WS_OVERLAPPEDWINDOW,
  116.         CW_USEDEFAULT, 0, 500, 400, NULL, NULL, hInstance, NULL);
  117.  
  118.     if (!hWnd)
  119.     {
  120.         return FALSE;
  121.     }
  122.  
  123.     MSG msg;
  124.  
  125.     while (GetMessage(&msg, NULL, 0, 0) > 0) {
  126.         DispatchMessage(&msg);
  127.     }
  128.  
  129.     return (int)msg.wParam;
  130. }

 

〇実行結果