window下線程同步之(Semaphores(信號量))


HANDLE WINAPI CreateSemaphore( 
  _In_opt_  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes 
  _In_      LONG lInitialCount, 
  _In_      LONG lMaximumCount, 
  _In_opt_  LPCTSTR lpName 
); 

第一個參數:安全屬性,如果為NULL則是默認安全屬性
第二個參數:信號量的初始值,要>=0且<=第三個參數
第三個參數:信號量的最大值
第四個參數:信號量的名稱
返回值:指向信號量的句柄,如果創建的信號量和已有的信號量重名,那么返回已經存在的信號量句柄

使用方法:
1、創建一個信號量:CreateSemaphore;
2、打開一個已經存在的信號量:OpenSemaphore;
3、獲得信號量的一個占有權:WaitForSingleObject、WaitForMultipleObjects 等一類等待的函數……(可能造成阻塞);
4、釋放信號量的占有權:ReleaseSemaphore;
5、關閉信號量:CloseHandle;

※ 命名標准:Semaphores 可以跨進程使用,所以其名稱對整個系統而言是全局的,所以命名不要過於普通,類似:Semaphore、Object 等。
最好想一些獨一無二的名字等!

固有特點(優點+缺點):
1、是一個系統核心對象,所以有安全描述指針,用完了要 CloseHandle 關閉句柄,這些是內核對象的共同特征;
2、因為是核心對象,所以執行速度稍慢(當然只是相比較而言);
3、因為是核心對象,而且可以命名,所以可以跨進程使用;
4、Semaphore 使用正確的情況下不會發生死鎖;
5、在“等待”一個 信號量 的時候,可以指定“結束等待”的時間長度;
6、非排他性的占有,跟 Critical Sections 和 Mutex 不同,這兩種而言是排他性占有,
即:同一時間內只能有單一線程獲得目標並擁有操作的權利,而 Semaphores 則不是這樣,
同一時間內可以有多個線程獲得目標並操作!

信號量沒有線程所有權屬性,即一個線程獲得某個信號量后,在他釋放該信號量之前,他不能再次進入信號量保護的區域

信號量的使用規則:

1. 如果當前資源計數大於0,那么信號量處於觸發狀態;

2. 如果當前資源計數等於0,那么信號量處於未觸發狀態;那么系統會讓調用線程進入等待狀態。

CreateSemaphore(NULL,0,1,NULL); 當第二個參數為0時,調用線程就會進入等待狀態

3. 系統絕對不會讓當前資源計數變為負數;

4. 當前資源計數絕對不會大於最大資源計數。

#include <iostream> 
#include <windows.h> 
using namespace std;

const int g_Number = 3; 
DWORD WINAPI ThreadProc1(__in  LPVOID lpParameter); 
DWORD WINAPI ThreadProc2(__in  LPVOID lpParameter); 
DWORD WINAPI ThreadProc3(__in  LPVOID lpParameter);

HANDLE hSemp1,hSemp2,hSemp3;

int main() 
{ 
   hSemp1 = CreateSemaphore(NULL,1,1,NULL); 
   hSemp2 = CreateSemaphore( NULL,1,1,NULL); 
   hSemp3 = CreateSemaphore(NULL,1,1,NULL);

    HANDLE hThread[ g_Number ] = {0}; 
    int first = 1, second = 2, third = 3; 
    hThread[ 0 ] = CreateThread(NULL,0,ThreadProc1,(LPVOID)first,0,NULL); 
    hThread[ 1 ] = CreateThread(NULL,0,ThreadProc2,(LPVOID)second,0,NULL); 
    hThread[ 2 ] = CreateThread(NULL,0,ThreadProc3,(LPVOID)third,0,NULL);

    WaitForMultipleObjects(g_Number,hThread,TRUE,INFINITE); 
    CloseHandle( hThread[0] ); 
    CloseHandle( hThread[1] ); 
    CloseHandle( hThread[2] );

    CloseHandle( hSemp1 ); 
    CloseHandle( hSemp2 ); 
    CloseHandle( hSemp3 ); 
    return 0; 
}

DWORD WINAPI ThreadProc1(__in  LPVOID lpParameter) 
{ 
    WaitForSingleObject(hSemp1, INFINITE);//等待信號量 
    cout<<(int)lpParameter<<endl; 
    ReleaseSemaphore(hSemp1,1,NULL);//釋放信號量 
    return 0; 
}

DWORD WINAPI ThreadProc2(__in  LPVOID lpParameter) 
{ 
    WaitForSingleObject(hSemp2, INFINITE);//等待信號量 
    cout<<(int )lpParameter<<endl; 
    ReleaseSemaphore(hSemp2,1,NULL);//釋放信號量 
    return 0; 
}

DWORD WINAPI ThreadProc3(__in  LPVOID lpParameter) 
{ 
    WaitForSingleObject( hSemp3, INFINITE);//等待信號量 
    cout<<(int)lpParameter<<endl; 
    ReleaseSemaphore(hSemp3,1,NULL);//釋放信號量 
    return 0; 
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM