您好,登錄后才能下訂單哦!
一 、同步機制的引入目的是為了解決三個主要問題
1為了控制線程之間共享資源的同步訪問,保證共享資源的完整性.(比如一個線程正在更新一個數據,而另外一個線程正在讀取該數據,那么就不知道該數據是新的還是舊的,為了避免這種狀況的發生)
2確保線程之間的動作,以制定的次序發送,例如一個線程的觸發,需要另外一個線程的結果,作為條件。
3為了控制某一個共享資源的最大訪問量,例如我們同時只能處理5個客戶的請求,這時候,我們需要放到隊列進行等待。
二、同步概念就是等待
WIN32 提供了API 等待函數
DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
參數1 :hHandle對象句柄. 可以制定一系列的對象,如
Event(事件),Mutex(互斥),Seamphore(信號)Thread(線程)等
參數2:dwMilliseconds 定時時間間隔 單位milliseconds(毫秒)
1如果指定一個非零值,函數處于等待狀態,直到hHandle標記的對象被觸發, 或者時間到了.
2如果dwMilliseconds為0,對象沒有被觸發信號,函數不會進入一個等待狀態,它立即返回.
3如果dwMilliseconds為INFINITE,對象被觸發,信號,函數才會返回,大部分情況下只使用INFINITE這個宏.
這個函數是一個堵塞的函數,意味著,只有這個函數運行完成才進行返回.因此他是一個同步的函數.
返回值:
DWORD dw = WaitForSingleObject(hProcess,5000)
{
//在指定之間內,代表等待成功,觸發了對象。
case WAIT_OBJECT_0:
//相應操作
break;
//等待時間結束,對象沒觸發,沒有成功 說明超時了
case WAIT_TIMEOUT:
//相應操作
break;
//發生了一些錯誤 ,可以線程句柄是NULL
case WAIT_FAILED:
//相應操作
break;
}
三、Mutex互斥量對象(同步對象)
作用:
1 用于確保一個線程獨占對于一個資源的訪問
2 包含一個使用計數器,線程ID,以及一個遞歸計數
3 線程的id用來標識當前占用這個互斥量的是系統中的哪個線程
4 遞歸計數器表示這個線程占用該互斥量的次數
5 互斥量是使用最為頻繁的內核對象之一
主要是當某個共享資源被某個,線程進行加鎖操作后,其他的線程就無法訪問該資源,進行讀寫.
1創建互斥量對象:
CreateMutex函數功能是建立互斥體對象,返回的就是這個對象
HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, //指向安全屬性的指針
BOOL bInitialOwner //初始化互斥對象所有者
LPCTSTR lpName //指向互斥對象名的
)
參數1正常情況下使用NULL,如果我們使用跨進錯的訪問。
參數2 通常為FALSE,那么線程ID和遞歸計數器,都被設置為0.
參數3 指定互斥體對象名字,如果以及存在擁有這個,名字的一個事件,則打開現有的已命名互斥體,這個名字可能不予現有的事件,信號機,可等待計時器或文件映射相符。
通常用法:HANDLE Mutex = CreateMutex(NULL,FALSE,NUKL);
2釋放互斥量對象:
ReleaseMutex函數
BOOL WINAPI ReleaseMutex(
HANDLE hMutex);
hMutex: 互斥對象的句柄
作用:這個函數會將對象的遞歸計數器減1,如果線程成功的等待了互斥量對象不止一次,那么線程必須調用release相同的次數
才能使對象的遞歸計數器變為0.當遞歸計數器為0時,函數還將線程ID設為0,使互斥量處于觸發狀態.
我們發現互斥量對象的遞歸計數器和id創建的時候就是0(也就是處于觸發狀態),那什么時候會增加使他非觸發狀態.
3整個互斥量的操作流程: (加鎖和解鎖流程)
假設:有一個全局的文件指針,同時又有多個線程,需要對該文件 指針進行讀寫,但是,為了保證資源的完整性,我們在同一時刻,
只允許一個線程進行讀寫操作。
加鎖:
為了獲得對被保護的資源的訪問權,線程要調用一個等待函數并轉入前面創建的互斥量句柄,在內部,等待函數會檢查線程ID是否為0(如果為0也就是觸發狀態)如果為0,那么函數會把互斥量句柄中的線程ID設為當前調用線程的ID,(只有這個加鎖的線程,才
允許對資源進行讀寫訪問操作 。)并把遞歸計數器設為1,此時
互斥量就處于非觸發狀態,對互斥量的線程id賦值和遞歸計數器增加,都是原子操作的,所謂的原子操作,就是指操作系統保證在完成原子操作之前,不進行線程的切換,然后當前線程繼續運行。
解鎖:
假設某一個線程成功的得到了互斥量,線程就知道自己獨占了對受保護的資源的訪問權, 那么任何視圖通過等待互斥量,來獲得
對資源的訪問權的線程,將進入等待狀態,很重要的一點是:當線程進入等待狀態后,是不消耗Cpu時鐘頻率的.當獨占線程對資源
操作完后, 必須調用ReleaseMutex函數(釋放)來將互斥量的遞歸計數器減1 ,如果遞歸計數器的值為0的話,那么還會將線程id
設置為0,這樣互斥量又處于觸發狀態了。
互斥量的注意點:
1線程id和遞歸計數器遞增只能在wait(等待)函數中操作.
2必須要調用release函數,否則會一直遞增導致死鎖。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。