CreateSemaphore関数でセマフォを作成します。

 

WaitForSingleObject関数で実行を制御できます。

 

〇プログラム例

セマフォ オブジェクトの最大カウントを設定して、

同時に実行できるスレッド数を決めます。

 

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

 

〇実行結果

円が下に下がるように描画されます。

同時に描画されるのは3つまでです。