搜索
熱搜: 活動 交友 discuz
查看: 1882|回復: 0
打印 上一主題 下一主題

[教學] C++多執行緒(七)

[複製鏈接]
跳轉到指定樓層
1#
發表於 2007-8-14 04:46:02 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

  1. 一 信標Semaphore
  2. 信標內核對像用於對資源進行計數。它們與所有內核對像一樣,包含一個使用數量,但是它們也包含另外兩個帶符號的3 2位值,一個是最大資源數量,一個是當前資源數量。最大資源數量用於標識信標能夠控制的資源的最大數量,而當前資源數量則用於標識當前可以使用的資源的數量。
  3. 為了正確地說明這個問題,讓我們來看一看應用程序是如何使用信標的。比如說,我正在開發一個服務器進程,在這個進程中,我已經分配了一個能夠用來存放客戶機請求的緩衝區。我對緩衝區的大小進行了硬編碼,這樣它每次最多能夠存放5個客戶機請求。如果5個請求尚未處理完畢時,一個新客戶機試圖與服務器進行聯繫,那麼這個新客戶機的請求就會被拒絕,並出現一個錯誤,指明服務器現在很忙,客戶機應該過些時候重新進行聯繫。當我的服務器進程初始化時,它創建一個執行緒池,裡面包含5個執行緒,每個執行緒都準備在客戶機請求到來時對它進行處理。
  4. 開始時,沒有客戶機提出任何請求,因此我的服務器不允許執行緒池中的任何執行緒成為可調度執行緒。但是,如果3個客戶機請求同時到來,那麼執行緒池中應該有3個執行緒處於可調度狀態。使用信標,就能夠很好地處理對資源的監控和對執行緒的調度,最大資源數量設置為5,因為這是我進行硬編碼的緩衝區的大小。當前資源數量最初設置為0,因為沒有客戶機提出任何請求。當客戶機的請求被接受時,當前資源數量就遞增,當客戶機的請求被提交給服務器的執行緒池時,當前資源數量就遞減。
  5. 信標的使用規則如下:
  6. . 如果當前資源的數量大於0,則發出信標信號。
  7. . 如果當前資源數量是0,則不發出信標信號。
  8. . 系統決不允許當前資源的數量為負值。
  9. . 當前資源數量決不能大於最大資源數量。
  10. 當使用信標時,不要將信標對象的使用數量與它的當前資源數量混為一談。

  11. 二 API

  12. [tr]            Semaphore function            Description        [/tr]         CreateSemaphore Creates or opens a named or unnamed semaphore object.
  13.          CreateSemaphoreEx Creates or opens a named or unnamed semaphore object and returns a handle to the object.
  14.          OpenSemaphore Opens an existing named semaphore object.
  15.          ReleaseSemaphore Increases the count of the specified semaphore object by a specified amount.

  16. 三 實例
  17. #include <windows.h>
  18. #include <stdio.h>

  19. #define MAX_SEM_COUNT 6
  20. #define THREADCOUNT 12

  21. HANDLE ghSemaphore;

  22. DWORD WINAPI ThreadProc( LPVOID );

  23. void main()
  24. {
  25.     HANDLE aThread[THREADCOUNT];
  26.     DWORD ThreadID;
  27.     int i;

  28.     // Create a semaphore with initial and max counts of MAX_SEM_COUNT

  29.     ghSemaphore = CreateSemaphore(
  30.         NULL,           // default security attributes
  31.         MAX_SEM_COUNT,  // initial count
  32.         MAX_SEM_COUNT,  // maximum count
  33.         NULL);          // unnamed semaphore

  34.     if (ghSemaphore == NULL)
  35.     {
  36.         printf("CreateSemaphore error: %d\n"、GetLastError());
  37.         return;
  38.     }

  39.     // Create worker threads

  40.     for( i=0; i < THREADCOUNT; i++ )
  41.     {
  42.         aThread = CreateThread(
  43.                      NULL,       // default security attributes

  44. 0,          // default stack size
  45.                      (LPTHREAD_START_ROUTINE) ThreadProc、
  46.                      NULL,       // no thread function arguments

  47. 0,          // default creation flags

  48. &ThreadID); // receive thread identifier

  49.         if( aThread == NULL )
  50.         {
  51.             printf("CreateThread error: %d\n"、GetLastError());
  52.             return;
  53.         }
  54.     }

  55.     // Wait for all threads to terminate

  56.     WaitForMultipleObjects(THREADCOUNT、aThread、TRUE、INFINITE);

  57.     // Close thread and semaphore handles

  58.     for( i=0; i < THREADCOUNT; i++ )
  59.         CloseHandle(aThread);

  60.     CloseHandle(ghSemaphore);
  61. }

  62. DWORD WINAPI ThreadProc( LPVOID lpParam )
  63. {
  64.     DWORD dwWaitResult;
  65.     BOOL bContinue=TRUE;

  66.     while(bContinue)
  67.     {
  68.         // Try to enter the semaphore gate.

  69.         dwWaitResult = WaitForSingleObject(
  70.             ghSemaphore,   // handle to semaphore

  71. 3L);           // zero-second time-out interval

  72.         switch (dwWaitResult)
  73.         {
  74.             // The semaphore object was signaled.

  75. case WAIT_OBJECT_0:
  76.                 // TODO: Perform task
  77.                 printf("Thread %d: wait succeeded\n"、GetCurrentThreadId());
  78.                 bContinue=FALSE;            

  79.                 // Simulate thread spending time on task
  80.                 Sleep(5);

  81.                 for(int x =
  82. 0; x<
  83. 10; x++)
  84.                     printf("Thread %d task!\n",GetCurrentThreadId());

  85.                 // Relase the semaphore when task is finished

  86.                 if (!ReleaseSemaphore(
  87.                         ghSemaphore,  // handle to semaphore

  88. 1,            // increase count by one
  89.                         NULL) )       // not interested in previous count

  90. {
  91.                     printf("ReleaseSemaphore error: %d\n"、GetLastError());
  92.                 }
  93.                 break;

  94.             // The semaphore was nonsignaled、so a time-out occurred.

  95. case WAIT_TIMEOUT:
  96.                 printf("Thread %d: wait timed out\n"、GetCurrentThreadId());
  97.                 break;
  98.         }
  99.     }
  100.     return TRUE;
  101. }


  102. 四 參考 [url]http://msdn2.microsoft.com/en-us/library/ms686946.aspx[/url]

複製代碼
您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則

本論壇為非營利之網路平台,所有文章內容均為網友自行發表,不代表論壇立場!若涉及侵權、違法等情事,請告知版主處理。


Page Rank Check

廣告刊登  |   交換連結  |   贊助我們  |   服務條款  |   免責聲明  |   客服中心  |   中央分站

手機版|中央論壇

GMT+8, 2024-4-29 03:35 , Processed in 0.020765 second(s), 16 queries .

Powered by Discuz!

© 2005-2015 Copyrights. Set by YIDAS

快速回復 返回頂部 返回列表