1. 程式人生 > >不積矽步,無以至千里;不積小流,無以成江海

不積矽步,無以至千里;不積小流,無以成江海

執行緒與核心物件的同步

1為什麼使用核心物件實現執行緒同步

1.1使用者模式下實現執行緒同步特點

1)同步速度快

2)互鎖函式族只能對單值進行操作,無法是執行緒進入等待狀態。

3)臨界區可以使執行緒進入等待狀態,但是隻能用於同一個程序的多個執行緒。由於無法設定超時操作,因此容易進入死鎖狀態。

1.2核心模式下實現執行緒同步特點

1)核心物件機制的唯一缺點:速度慢。

2)優點:適用性強

2等待函式

2.1 WaitForSingleObject

等待函式使執行緒進入等待狀態,等待一個特定的核心物件變成已通知狀態。當執行緒等待物件的狀態為未通知狀態時,不能排程這個,執行緒,一旦核心物件變成已通知狀態,執行緒標誌變成可排程。

DWORD  WaitForSingleObject(

             HANDLE  hObject,

             DWORD  dwMilliseconds);

第一個引數hObject標識一個支援通知/未通知狀態的核心物件;第二個引數dwMillseconds指明等待物件變成已通知狀態所需的等待時間。當第二個引數為INFINITE-1)時,說明執行緒可以無限等待,直到程序終止執行。通常情況下,會使用INFINITE,如果物件一直未通知,執行緒將一直處於死鎖狀態,但是不會浪費處理器時間。

函式返回值:

WAIT_OBJECT_0               //等待物件變成已通知狀態

WAIT_TIMEOUT                //等待超時

WAIT_FAILED                     //傳遞錯誤引數,通過GetLastError()瞭解詳情

2.2 WaitForMultipleObject

         DWORD WaitForMultipleObject(

                   DWORD dwCount,

                   CONSTHANDLE*  phObjects,

                   BOOL fWaitAll,

                   DWORD dwMilliseconds);

第一個引數指明呼叫執行緒所檢視的核心物件的數量,在0-MAXIMUM_WAIT_OBJECTSwindows定義為64)之間;第二個引數是指向核心物件控制代碼陣列的指標;第三個引數fWaitAll指示兩種成功等待方式,一種需要所有核心物件變成已通知,另一種需要任意一個核心物件變成已通知;第四個引數同上。

返回值:

         WAIT_TIMEOUT;     

         WAIT_FAILED;

         WAIT_OBJECT_0;(fWaitallture)

         WAIT_OBJECT_0WAIT_OBJECT_0+dwCount-1之間的值(fWaitallfalse時,指示哪個物件變成已通知狀態)

3事件核心物件

事件核心物件是所有核心物件中最基本的。事件核心物件包含一個使用計數(所有核心物件都有),一個布林值,指示這個事件是自動重置事件還是人工重置事件。以及另外一個指示事件處於已通知狀態還是未通知狀態的布林值。

兩種事件物件:

人工重置事件:得到通知時,等待這個事件的所有執行緒變成可排程執行緒。

自動重置事件:得到通知時,等待這個事件的所有執行緒只有一個變成可排程執行緒。

3.1 建立事件核心物件

下面是用於建立事件核心物件的CreateEvent函式:

         HANDLE CreateEvent(

                   PSECURITY_ATTRIBUTES  psa,

                   BOOL  fManualReset,

                   BOOL  fInitialState,

                   PSTSTR  pszName)

第一個引數(PSECURITY_ATTRIBUTES)安全性描述符:描述建立物件的程序,以及哪些程序可以訪問物件,哪些不可以訪問;第二個引數fManualReset引數是一個布林值,用於指明建立人工重置事件還是自動重置事件;第三個引數fInitialState指明這個事件初始化為已通知狀態還是未通知狀態。第四個引數為事件命名;

3.2 核心物件的使用

其他程序中的執行緒可以通過pszName引數中傳遞的相同值,使用繼承性,使用DuplicateHandle等函式來獲得對這個物件的訪問權。或者通過呼叫OpenEvent,傳遞的pazName一致即可。

         HANDLE  OpenEvent(

                   DWORD  fdwAccess,

                   BOOL  bInherit,

                   PCTSTRpszName);

建立事件後,就可以直接控制這個事件的狀態。可以呼叫SetEvent將事件的狀態改為已通知,呼叫ResetEvent改為未通知狀態:

         BOOL  SetEvent(HANDLE  hEvent);

         BOOL  ResetEvent(HANDLE  hEvent);

不在需要使用該事件時,呼叫CloseHandle函式。

4 等待定時器核心物件

等待定時器是在某個時間或按照規定時間間隔,發出自己的訊號通知的核心物件。通常使用這些核心物件,在某個時間執行某個操作。

4.1建立等待定時器

HANDLE  CreateWaitableTimer(

         PSECURITY_ATTRIBUTES  psa,

         BOOL fManualReset,

         PSTSTR pszName);

程序也可以通過OpenWaitableTimer函式,來獲得與進場相關的等待定時器控制代碼。

HANDLE  OpenWaitableTimer(

         DWORD dwDesiedAccess,

         BOOL bInheritHandle,

         PSTSTR pszName)

4.2使用定時器

等待定時器總是設定為未通知狀態。可以呼叫SetWaitableTimer函式,來確定定時器何時變成已通知狀態:

BOOLSetWaitalbeTimer(

            HANDLE  hTime,

            const  LARGE_INTERGER*pDueTime

            LONG  lPeriod,

             PTIMERAPCOUTINE  pfnCompletionRoutine,

            PVOID pvArgToCompletionRoutine,

            BOOL  fResume);

         hTime:指明要設定的定時器物件

         pDueTime:指明定時器第一次報時時間;

         pPeriod:指明定時器第一次報時之後,定時器再次報時的時間間隔

5.訊號量核心物件

訊號量核心物件用來對資源進行計數,它與其他核心物件一樣,包含一個使用計數。同時包含兩個帶符號的32位數:一個最大資源數量,一個當前資源數量。

訊號量的使用規則:

l  當前資源的數量大於0時,發出訊號量訊號;

l  當前資源數量等於0時,不發出訊號量訊號;

l  當前資源數量不能為負值;

l  當前資源數量不能大於最大資源數量

使用訊號量時,不能將訊號量的物件的使用數量和當前資源數量混淆。

5.1訊號量建立

下面是建立訊號量核心物件的函式:

         HANDLECreateSemaphore(

                   PSECURITY_ATTRIBUTE  psa,

                   LONG  lInitialCount,

                   LONG  lMaximumCount,

                   PCTSTR  pszName);

         llMaximumCount表示應用程式處理的最大資源數量,這個引數是帶符號的32位值,因此最多可以擁有2147483647個資源;

         lInitialCount引數指明開始時(當前)資源中有多少資源可供使用。

呼叫OpenSemaphore函式,另外的程序也能獲取自己與現有訊號量相關的控制代碼:

         HANDLEOpenSemaphore(

                   DWORD  fdwAccess,

                   BOOL  bInitialCount,

                   PCTSTR  pszName);

可以呼叫ReleaseSemphore函式,對訊號量的當前資源數量進行遞增:

         BOOLReleaseSemaphore(

                   HANDLE  hsem,

                   LONG  lReleaseCount,

                   PLONG  plPreviousCount);

這個函式的功能是將引數lReleaseCount的值新增給訊號量當前的資源數量,通常為1.沒有函式可以查詢訊號量當前的資源數量。

具體題目:
在作業系統的程序管理中,若系統中有10個程序使用互斥資源R,每次只允許3個程序進入互斥段(臨界區),則訊號量S的變化範圍是______(1):若訊號量S的當前值為-2,則表示系統中有______(2)個正在等待該資源的程序。
(1)A.-7~1    B.-7~3    C.-3~0    D.-3~10
(2)A.0    B.1    C.2    D.3

B:S<0後請求R的程序將被阻塞,此時應該有3個程序獲得資源。
C:第一個分配後,S=2;第三個分配後,S=0;第四個程序請求時S=-1,等待資源;S=-2時既有兩個程序在等待。

關鍵是要分清:先S減一,還是先分配資源

6.互斥物件核心物件

6.1互斥物件

互斥物件確保執行緒能夠互斥的訪問一個資源,這也是這個物件如此命名的原因。互斥物件包含一個使用計數,一個執行緒ID和一個遞迴計數器。

互斥物件的使用規則如下:

l  若執行緒ID0,即無效ID,互斥物件不能被任何執行緒擁有。並且發出這個物件的通知訊號。

l  若執行緒ID是個非0值,那麼互斥物件被某一個執行緒擁有,並且不發出這個物件的通知訊號。

l  互斥物件在作業系統中擁有特殊的程式碼,允許互斥物件違反正常的規則,這與其他核心物件不同。

使用互斥物件之前,呼叫CreateMutex函式建立互斥物件。

HANDLECreateMutex(

          PSECURITY_ATTRIBUTES  pas;

          BOOL  fInitialOwner,

          PCTSTR  pszName);

另外的程序通過Ope nMutex獲得自身與現有互斥物件關聯的控制代碼

HANDLEOpenMutex(

         DWORD  fdwAccess,

         BOOL bIniheritHandle,

         PCTSTR pszName);

互斥物件所進行的所有檢查和修改操作都是以原子方式進行的。一旦執行緒等待到了一個互斥物件,執行緒就擁有對所保護資源的獨佔訪問權。執行緒呼叫ReleaseMutex函式釋放互斥物件,將互斥物件的引用計數-1

BOOL ReleaseMutex(HANDLE  hMutex);

“異常”:對於互斥物件來說,存在核心物件已通知或未通知的異常情況。假如一個執行緒正在等待一個未通知的互斥物件,那麼通常將這個執行緒置於等待狀態。然而系統會檢視試圖獲得互斥物件的執行緒ID,並與互斥物件記錄的執行緒ID進行比較.如果兩者相同,那麼即使互斥物件處於未通知狀態,系統也允許這個執行緒保持可排程狀態。

這個“異常”情況不適用於其他核心物件。因此要使遞迴計數器的值大於1,唯一的方法是使執行緒多次等待相同的互斥物件。釋放時需要多次呼叫ReleaseMutex,直到計數器的值為0

6.2 釋放問題

互斥物件和其他核心物件不同,有一個“執行緒所有權”的問題,其他核心物件無法記住哪個執行緒正在擁有這個物件,而互斥物件能夠對此保持跟蹤。這也是互斥物件擁有異常規則的原因。異常規則是的執行緒在物件沒有發出通知時,獲取這個物件。

當擁有互斥物件的執行緒在釋放這個物件前終止執行,系統則把這個互斥物件視為已經放棄。然後系統檢查是否有等待這個互斥物件的執行緒,並選擇其中一個。將互斥物件的執行緒ID設定為選定執行緒的ID,計數為1.

在這個過程中,等待函式返回的不是WAIT_OBJTCT_0,而是WAIT_ABANDONED,表示這個互斥物件被另一個執行緒佔有,而另一個程序在釋放物件前終止。

相關推薦

無以無以江海

執行緒與核心物件的同步 1為什麼使用核心物件實現執行緒同步 1.1使用者模式下實現執行緒同步特點 (1)同步速度快 (2)互鎖函式族只能對單值進行操作,無法是執行緒進入等待狀態。 (3)臨界區可以使執行緒進入等待狀態,但是隻能用於同一個程序的多個執行緒。由於無法設定超時

無以無以江海

一次磁碟讀寫操作的時間由尋找(尋道)時間、延遲時間和傳輸時間決定: 1) 尋找時間Ts:活動頭磁碟在讀寫資訊前,將磁頭移動到指定磁軌所需要的時間。這個時間除跨越n條磁軌的時間外,還包括啟動磁臂的時間s,即:Ts = m * n + s。式中,m是與磁碟驅動器速

無以無以江海

當你在職場面對無數競爭對手時,當你每年報考公務員考試看到數百上千人競爭三五個職位時……你大概也會像很多人那樣希望我們的計劃生育政策早實行幾十年吧。其實不只是你,很多思想家都對人與人之間的這種競爭關係做出過研究,並提出了很多各不相同的觀點。比如法國哲學家薩特說,他人就是地獄

【Utopia.Pro的部落格(Utopia.Pro's Blog)】無以無以江海

所在地:北京海淀  從事:iOS移動端開發。  技術討論群:536739494 郵箱:[email protected]  部落格內文章、視訊有錯誤或不妥之處,請您留言或郵件指明,不勝感激,發現會及時修正。 部落格內有些資料可

無以無以江海

由於垃圾收集演算法在各個虛擬機器以及不同的平臺上會有不同的實現,所以開頭先大概講解一下幾個基本的演算法 1. 引用計數(Reference Counting) 為每一個物件新增一個計數器,計數器記錄了對該物件的活躍引用的數量。如果計數器為0,則說明這個物件沒有被任何變數所引

無以致無以江海

二叉搜尋樹、平衡二叉樹、紅黑樹都屬於二叉樹,由於每個節點只有一個元素,每個節點只能連線兩個節點。對於像檔案系統、資料庫這樣需要數目龐大讀寫刪除操作,如果採用這種資料結構將會大大降低系統的效率,遇到I/O讀寫的瓶頸。 有沒有一種資料結構可以降低往返於節點之間的次數呢?答案是有

cbNotes的專欄:無以;無以江海!

CDocTemplate類的AddDocument、RemoveDocument成員函式使得CDocument* pDoc引數所指向的文件歸屬於本文件模板(通過將this指標賦值給pDoc所指向CDocument物件的m_pDocTemplate成員變數)或脫離與本文件模板的關係: void CDocTem

無以】聚優致

專欄達人 授予成功建立個人部落格專欄

無以】——初來乍到請多包涵^_^

初來乍到,請多關照O(∩_∩)O~ 由於技術能力有限,文章中難免會存在一些問題,歡迎糾正。純粹學習交流,如果博文侵犯了您的權利,請儘快聯絡我更正刪除: [email protected] 除寫博之外,興趣廣泛,我的豆瓣小站:

無以無以江海

 PL/SQL流程控制語句 介紹PL/SQL的流程控制語句, 包括如下三類:     控制語句: IF 語句     迴圈語句: LOOP語句, EXIT語句     順序語句: GOTO語句, NULL語句 ①if語句 IF <布林表示式> THEN   

Daniel 的技術筆記 無以無以江海

Hive是基於Hadoop的一個數據倉庫工具,可以將結構化的資料檔案對映為一張資料庫表,並提供完整的sql查詢功能,可以將sql語句轉換為 MapReduce任務進行執行。其優點學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapRed

菜鳥在努力-的專欄——無以

第一種:剔除2 3 4 5 6 ... ... 的倍數 在i從2開始的增一變化過程中,剔除i的倍數即j*i(j是大於等於2的自然數,j的上限是問題規模M) 為了減少重複步驟,可以每當i遞增到等於第一個沒有被剔除的(素)數時再剔除該數的倍數, 重複上述過程至i到達問題

【AdairZhao】無以

個人簡介 合肥中國科學技術大學訊號處理專業,資料探勘方向,目前供職於 成都螞蟻金服,歡迎加入螞蟻,為世界作出微小的貢獻。長期內推薦郵箱 [email protected];方向資料探勘、JAVA開發、演算法均可。

無以無以江海

 // GB2312的字符集的筆劃列表,可以參考gb2312字元全集  private static int[] gb2312StrokeCount = {  /* B0 */    10,7,10, 10, 8, 10, 9, 11, 17, 14, 13, 5, 13, 10, 12, 15, 10, 6

無以】個人部落格地址:https://lewky.cn

/*** * --------------攻城獅-------------- * ,%%%%%%%%, * ,%%/\%%%%/\%% * ,%%%\c "" J/%%% * %. %%%%/

無以(個人部落格地址:https://lewky.cn)

/*** * --------------攻城獅-------------- * ,%%%%%%%%, * ,%%/\%%%%/\%% * ,%%%\c "" J/%%% * %. %%%%/

無以無以江海

我們在開發中用了許多載入圖片的框架都封裝了快取機制,圖片的三級快取的核心類就是LruCache類,嘗試手寫三級快取工具類: /** * 自定義的載入網路圖片工具:三級快取 * @author wangk * */ public class MyBi