1. 程式人生 > >Windows核心程式設計 第九章 執行緒與核心物件的同步(上)

Windows核心程式設計 第九章 執行緒與核心物件的同步(上)

第9章 執行緒與核心物件的同步

    上一章介紹瞭如何使用允許執行緒保留在使用者方式中的機制來實現執行緒同步的方法。使用者方式同步的優點是它的同步速度非常快。如果強調執行緒的執行速度,那麼首先應該確定使用者方式的執行緒同步機制是否適合需要。

    雖然使用者方式的執行緒同步機制具有速度快的優點,但是它也有其侷限性。對於許多應用程式來說,這種機制是不適用的。例如,互鎖函式家族只能在單值上執行,根本無法使執行緒進入等待狀態。可以使用關鍵程式碼段使執行緒進入等待狀態,但是隻能用這些程式碼段對單個程序中的執行緒實施同步。還有,使用關鍵程式碼段時,很容易陷入死鎖狀態,因為在等待進入關鍵程式碼段時無法設定超時值。

    本章將要介紹如何使用核心物件來實現執行緒的同步。你將會看到,核心物件機制的適應性遠遠優於使用者方式機制。實際上,核心物件機制的唯一不足之處是它的速度比較慢。當呼叫本章中提到的任何新函式時,呼叫執行緒必須從使用者方式轉為核心方式。這個轉換需要很大的代價:往返一次需要佔用 x 8 6平臺上的大約1 0 0 0C P U週期,當然,這還不包括執行核心方式程式碼,即實現執行緒呼叫的函式的程式碼所需的時間。

    本書介紹了若干種核心物件,包括程序,執行緒和作業。可以將所有這些核心物件用於同步目的。對於執行緒同步來說,這些核心物件中的每種物件都可以說是處於已通知或未通知的狀態之中。這種狀態的切換是由

M i c r o s o f t為每個物件建立的一套規則來決定的。例如,程序核心物件總是在未通知狀態中建立的。當程序終止執行時,作業系統自動使該程序的核心物件處於已通知狀態。一旦程序核心物件得到通知,它將永遠保持這種狀態,它的狀態永遠不會改為未通知狀態。

    當程序正在執行的時候,程序核心物件處於未通知狀態,當程序終止執行的時候,它就變為已通知狀態。程序核心物件中是個布林值,當物件建立時,該值被初始化為 FA L S E(未通知狀態) 。當程序終止執行時,作業系統自動將對應的物件布林值改為 T R U E,表示該物件已經得到通知。

    如果編寫的程式碼是用於檢查程序是否仍在執行,那麼只需要呼叫一個函式,讓作業系統去

    檢查程序物件的布林值,這非常簡單。你也可能想要告訴系統使執行緒進入等待狀態,然後當布林值從FA L S E改為T R U E時自動喚醒該執行緒。這樣,你可以編寫一個程式碼,在這個程式碼中,需要等待子程序終止執行的父程序中的執行緒只需要使自己進入睡眠狀態,直到標識子程序的核心物件變為已通知狀態即可。你將會看到, M i c r o s o f tWi n d o w s提供了一些能夠非常容易地完成這些操作的函式。

    剛才講了M i c r o s o f t為程序核心物件定義了一些規則。實際上,執行緒核心物件也遵循同樣的規則。即執行緒核心物件總是在未通知狀態中建立。當執行緒終止執行時,作業系統會自動將執行緒物件的狀態改為已通知狀態。因此,可以將相同的方法用於應用程式,以確定執行緒是否不再執行。與程序核心物件一樣,執行緒核心物件也可以處於已通知狀態或未通知狀態。

    下面的核心物件可以處於已通知狀態或未通知狀態:

    ■ 程序 ■ 檔案修改通知

    ■ 執行緒 ■ 事件

    ■ 作業 ■ 可等待定時器

    ■ 檔案 ■ 信標

    ■ 控制檯輸入 ■ 互斥物件

    執行緒可以使自己進入等待狀態,直到一個物件變為已通知狀態。注意,用於控制每個物件的已通知/未通知狀態的規則要根據物件的型別而定。前面已經提到程序和執行緒物件的規則及作業的規則。

9.1 等待函式

    等待函式可使執行緒自願進入等待狀態,直到一個特定的核心物件變為已通知狀態為止。這些等待函式中最常用的是Wa i t F o r S i n g l e O b j e c t :

DWORD WaitForSingObject(

HANDLE hObject,

DWORD dwMilliseconds);

    當執行緒呼叫該函式時,第一個引數 h O b j e c t標識一個能夠支援被通知 /未通知的核心物件(前面列出的任何一種物件都適用) 。第二個引數d w M i l l i s e c o n d s允許該執行緒指明,為了等待該物件變為已通知狀態,它將等待多長時間。

    呼叫下面這個函式將告訴系統,呼叫函式準備等待到h P r o c e s s控制代碼標識的程序終止執行為止:

    WaitForSingleObject(hProcess ,INFINITE);

    第二個引數告訴系統,呼叫執行緒願意永遠等待下去(無限時間量) ,直到該程序終止執行。

    通常情況下,I N F I N I T E是作為第二個引數傳遞給Wa i t F o r S i n g l e O b j e c t的,不過也可以傳遞任何一個值(以毫秒計算) 。順便說一下,I N F I N I T E已經定義為0 x F F F F F F F F(或-1) 。當然,傳遞I N F I N I T E有些危險。如果物件永遠不變為已通知狀態,那麼呼叫執行緒永遠不會被喚醒,它將永遠處於死鎖狀態,不過,它不會浪費寶貴的C P U時間。

    下面是如何用一個超時值而不是I N F I N I T E來呼叫Wa i t F o r S i n g l e O b j e c t的例子:

 

    上面這個程式碼告訴系統,在特定的程序終止執行之前,或者在 5 0 0 0 m s時間結束之前,呼叫執行緒不應該變為可排程狀態。因此,如果程序終止執行,那麼這個函式呼叫將在不到5 0 0 0 m s的時間內返回,如果程序尚未終止執行,那麼它在大約 5 0 0 0 m s時間內返回。注意,不能為d w M i l l i s e c o n d傳遞0。如果傳遞了0Wa i t F o r S i n g l e O b j e c t函式將總是立即返回。

    Wa i t F o r S i n g l e O b j e c t的返回值能夠指明呼叫執行緒為什麼再次變為可排程狀態。如果執行緒等待的物件變為已通知狀態,那麼返回值是 WA I T _ O B J E C T _ 0。如果設定的超時已經到期,則返回值是WA I T _ T I M E O U T。如果將一個錯誤的值(如一個無效控制代碼)傳遞給 Wa i t F o r S i n g l eO b j e c t,那麼返回值將是WA I T _ FA I L E D(若要了解詳細資訊,可呼叫G e t L a s t E r r o r) 。

    下面這個函式Wa i t F o r M u l t i p l e O b j e c t sWa i t F o r S i n g l e O b j e c t函式很相似,區別在於它允許呼叫執行緒同時檢視若干個核心物件的已通知狀態:

DWORD WaitForMultipleObjects(

    DWORD dwCount,

    CONST HANDLE*phObjects,

    BOOL fWaitAll,

    DWORD dwMilliseconds

);

     d w C o u n t引數用於指明想要讓函式檢視的核心物件的數量。這個值必須在 1M A X I M U M _WA I T _ O B J E C T S(在Wi n d o w s標頭檔案中定義為6 4)之間。p h O b j e c t s引數是指向核心物件控制代碼的陣列的指標。

可以以兩種不同的方式來使用Wa i t F o r M u l t i p l e O b j e c t s函式。一種方式是讓執行緒進入等待狀態,直到指定核心物件中的任何一個變為已通知狀態。另一種方式是讓執行緒進入等待狀態,直到所有指定的核心物件都變為已通知狀態。 f Wa i tAl l引數告訴該函式,你想要讓它使用何種方式。如果為該引數傳遞T R U E,那麼在所有物件變為已通知狀態之前,該函式將不允許呼叫執行緒執行。

    d w M i l l i s e c o n d s引數的作用與它在Wa i t F o r S i n g l e O b j e c t中的作用完全相同。如果在等待的時候規定的時間到了,那麼該函式無論如何都會返回。同樣,通常為該引數傳遞 I N F I N I T E,但是在編寫程式碼時應該小心,以避免出現死鎖情況。

    Wa i t F o r M u l t i p l e O b j e c t s函式的返回值告訴呼叫執行緒,為什麼它會被重新排程。可能的返回值是WA I T _ FA I L E DWA I T _ T I M E O U T,這兩個值的作用是很清楚的。如果為 f Wa i tAl l引數傳遞T R U E,同時所有物件均變為已通知狀態,那麼返回值是WA I T _ O B J E C T _ 0。如果為f Wa i t A l l傳遞FA L S E,那麼一旦任何一個物件變為已通知狀態,該函式便返回。在這種情況下,你可能想要知道哪個物件變為已通知狀態。返回值是WA I T _ O B J E C T _ 0與(WA I T _ O B J E C T _ 0 + d w C o u n t - 1)之間的一個值。換句話說,如果返回值不是WA I T _ T I M E O U T,也不是WA I T _ FA I L E D,那麼應該從返回值中減去WA I T _ O B J E C T _ 0。產生的數字是作為第二個引數傳遞給Wa i t F o r M u l t i p l e O b j e c t s的控制代碼陣列中的索引。該索引說明哪個物件變為已通知狀態。下面是說明這一情況的一些示例程式碼:

 

    如果為f Wa i t A l l引數傳遞FA L S EWa i t F o r M u l t i p l e O b j e c t s就從索引0開始向上對控制代碼陣列進行掃描,同時已通知的第一個物件終止等待狀態。這可能產生一些你不希望有的結果。例如,通過將3個程序控制代碼傳遞給該函式,你的執行緒就會等待 3個子程序終止執行。如果陣列中索引為0的程序終止執行,Wa i t F o r M u l t i p l e O b j e c t s就會返回。這時該執行緒就可以做它需要的任事情,然後迴圈反覆,等待另一個程序終止執行。如果該執行緒傳遞相同的 3個控制代碼,該函式立即再次返回WA I T _ O B J E C T _ 0。除非刪除已經收到通知的控制代碼,否則程式碼就無法正確地執行。

9.2 成功等待的副作用

    對於有些核心物件來說,成功地呼叫 Wa i t F o r S i n g l e O b j e c tWa i t F o r M u l t i p l e O b j e c t s,實際上會改變物件的狀態。成功地呼叫是指函式發現物件已經得到通知並且返回一個相對於WA I T _ O B J E C T _ 0的值。如果函式返回WA I T _ T I M E O U TWA I T _ FA I L E D,那麼呼叫就沒有成功。如果函式呼叫沒有成功,物件的狀態就不可能改變。

    當一個物件的狀態改變時,我稱之為成功等待的副作用。例如,有一個執行緒正在等待自動清除事件物件(本章後面將要介紹) 。當事件物件變為已通知狀態時,函式就會發現這個情況,並將WA I T _ O B J E C T _ 0返回給呼叫執行緒。但是就在函式返回之前,該事件將被置為未通知狀態,這就是成功等待的副作用。

這個副作用將用於自動清除核心物件,因為它是 M i c r o s o f t為這種型別的物件定義的規則之一。其他物件擁有不同的副作用,而有些物件則根本沒有任何副作用。程序和執行緒核心物件就根本沒有任何副作用,也就是說,在這些物件之一上進行等待決不會改變物件的狀態。由於本章要介紹各種不同的核心物件,因此我們將要詳細說明它們的成功等待的副作用。

    究竟是什麼原因使得Wa i t F o r M u l t i p l e O b j e c t s函式如此有用呢,因為它能夠以原子操作方式來執行它的所有操作。當一個執行緒呼叫Wa i t F o r M u l t i p l e O b j e c t s函式時,該函式能夠測試所有物件的通知狀態,並且能夠將所有必要的副作用作為一項操作來執行。

讓我們觀察一個例子。兩個執行緒以完全相同的方式來呼叫 Wa i t F o r M u l t i p l e O b j e c t s

 

    當Wa i t F o r M u l t i p l e O b j e c t s函式被呼叫時,兩個事件都處於未通知狀態,這就迫使兩個執行緒都進入等待狀態。然後h A u t o R e s e t E v e n t 1物件變為已通知狀態。兩個執行緒都發現,該事件已經變為已通知狀態,但是它們都無法被喚醒,因為 h A u t o R e s e t E v e n t 2仍然處於未通知狀態。由於兩個執行緒都沒有等待成功,因此沒有對h A u t o R e s e t E v e n t 1物件產生任何副作用。

    接著,h A u t o R e s e t E v e n t 2變為已通知狀態。這時,兩個執行緒中的一個發現,兩個物件都變為已通知狀態。等待取得了成功,兩個事件物件均被置為未通知狀態,該執行緒變為可排程的執行緒。但是另一個執行緒的情況如何呢?它將繼續等待,直到它發現兩個事件物件都處於已通知狀態。儘管它原先發現 h A u t o R e s e t E v e n t 1處於已通知狀態,但是現在它將該物件視為未通知狀態。

    前面講過,有一個重要問題必須注意,即Wa i t F o r M u l t i p l e O b j e c t s是以原子操作方式執行的。當它檢查核心物件的狀態時,其他任何執行緒都無法揹著物件改變它的狀態。這可以防止出現死鎖情況。試想,如果一個執行緒看到h A u t o R e s e t E v e n t 1已經得到通知並將事件重置為未通知狀態,然後,另一個執行緒發現h A u t o R e s e t E v e n t 2已經得到通知並將該事件重置為未通知狀態,那麼這兩個執行緒均將被凍結:一個執行緒將等待另一個執行緒已經得到的物件,另一個執行緒將等待該執行緒已經得到的物件。Wa i t F o r M u l t i p l e O b j e c t s能夠確保這種情況永遠不會發生。

    這會產生一個非常有趣的問題,即如果多個執行緒等待單個核心物件,那麼當該物件變成已通知狀態時,系統究竟決定喚醒哪個執行緒呢? M i c r o s o f t對這個問題的正式回答是: “演算法是公平的。 ”M i c r o s o f t不想使用系統使用的內部演算法。它只是說該演算法是公平的,這意味著如果多個執行緒正在等待,那麼每當物件變為已通知狀態時,每個執行緒都應該得到它自己的被喚醒的機會。

    這意味著執行緒的優先順序不起任何作用,即高優先順序執行緒不一定得到該物件。這還意味著等待時間最長的執行緒不一定得到該物件。同時得到物件的執行緒有可能反覆迴圈,並且再次得到該物件。但是,這對於其他執行緒來說是不公平的,因此該演算法將設法防止這種情況的出現。但是這不一定做得到。

    在實際操作中,M i c r o s o f t使用的演算法是常用的“先進先出”的方案。等待了最長時間的執行緒將得到該物件。但是系統中將會執行一些操作,以便改變這個行為特性,使它不太容易預測。這就是為什麼M i c r o s o f t沒有明確說明該演算法如何起作用的原因。操作之一是讓執行緒暫停執行。如果一個執行緒等待一個物件,然後該執行緒暫停執行,那麼系統就會忘記該執行緒正在等待該物件。這是一個特性,因為沒有理由為一個暫停執行的執行緒進行排程。當後來該執行緒恢復執行時,系統將認為該執行緒剛剛開始等待該物件。

    當除錯一個程序時,只要到達一個斷點,該程序中的所有執行緒均暫停執行。因此,除錯一個程序會使“先進先出”的演算法很難預測其結果,因為執行緒常常暫停執行,然後再恢復執行。

9.3 事件核心物件

    在所有的核心物件中,事件核心物件是個最基本的物件。它們包含一個使用計數(與所有核心物件一樣) ,一個用於指明該事件是個自動重置的事件還是一個人工重置的事件的布林值,另一個用於指明該事件處於已通知狀態還是未通知狀態的布林值。

    事件能夠通知一個操作已經完成。有兩種不同型別的事件物件。一種是人工重置的事件,另一種是自動重置的事件。當人工重置的事件得到通知時,等待該事件的所有執行緒均變為可排程執行緒。當一個自動重置的事件得到通知時,等待該事件的執行緒中只有一個執行緒變為可排程執行緒。

    當一個執行緒執行初始化操作,然後通知另一個執行緒執行剩餘的操作時,事件使用得最多。事件初始化為未通知狀態,然後,當該執行緒完成它的初始化操作後,它就將事件設定為已通知狀態。這時,一直在等待該事件的另一個執行緒發現該事件已經得到通知,因此它就變成可排程執行緒。這第二個執行緒知道第一個執行緒已經完成了它的操作。

    下面是C r e a t e E v e n t函式,用於建立事件核心物件:

HANDLE CrreateEvent(

  PSECURITY_ATTRIBUTES psa,

  BOOL fManualReset,

  BOOL fInitialState,

  PCTSTR pszName

);

    第3章已經介紹了核心物件的操作技巧,比如,如何設定它們的安全性,如何進行使用計數,如何繼承它們的控制代碼,如何按名字共享物件等。由於現在你對所有這些物件都已經熟悉了,所以不再介紹該函式的第一個和最後一個引數。

    F M a n n u a l R e s e t引數是個布林值,它能夠告訴系統是建立一個人工重置的事件( T R U E)還是建立一個自動重置的事件( FA L S E) 。f I n i t i a l S t a t e引數用於指明該事件是要初始化為已通知狀態(T R U E)還是未通知狀態(FA L S E) 。當系統建立事件物件後,c r e a t e E v e n t就將與程序相關的控制代碼返回給事件物件。其他程序中的執行緒可以獲得對該物件的訪問權,方法是使用在p s z N a m e引數中傳遞的相同值,使用繼承性,使用 D u p l i c a t e H a n d l e函式等來呼叫C r e a t e E v e n t,或者呼叫O p e n E v e n t ,p s z N a m e引數中設定一個與呼叫C r e a t e E v e n t時設定的名字相匹配的名字:

HANDLE OpenEvent(

    DWORD fdwAccess,

    BOOL fInherit,

    PCTSTR pszName

);

    與所有情況中一樣,當不再需要事件核心物件時,應該呼叫C l o s e H a n d l e函式。

    一旦事件已經建立,就可以直接控制它的狀態。當呼叫 S e t E v e n t時,可以將事件改為已通知狀態:

    BOOL SetEvent(HANDLE hEvent);

    當呼叫R e s e t E v e n t函式時,可以將該事件改為未通知狀態:

    BOOL ResetEvent(HANDLE hEvent);

    M i c r o s o f t為自動重置的事件定義了應該成功等待的副作用規則,即當執行緒成功地等待到該物件時,自動重置的事件就會自動重置到未通知狀態。這就是自動重置的事件如何獲得它們的名字的方法。通常沒有必要為自動重置的事件呼叫 R e s e t E v e n t函式,因為系統會自動對事件進行重置。但是,M i c r o s o f t沒有為人工重置的事件定義成功等待的副作用。

    讓我們觀察一個簡單的例子,以便說明如何使用事件核心物件對執行緒進行同步。下面就是這個程式碼:

 


    當這個程序啟動時,它建立一個人工重置的未通知狀態的事件,並且將控制代碼儲存在一個全域性變數中。這使得該程序中的其他執行緒能夠非常容易地訪問同一個事件物件。現在 3個執行緒已經產生。這些執行緒要等待檔案的內容讀入記憶體,然後每個執行緒都要訪問它的資料。一個執行緒進行單詞計數,另一個執行緒執行拼寫檢查器,第三個執行緒執行語法檢查器。這 3個執行緒函式的程式碼的開始部分都相同,每個函式都呼叫 Wa i t F o r S i n g l e O b j e c t,這將使執行緒暫停執行,直到檔案的內容由主執行緒讀入記憶體為止。

    一旦主執行緒將資料準備好,它就呼叫 S e t E v e n t,給事件發出通知訊號。這時,系統就使所有這3個輔助執行緒進入可排程狀態,它們都獲得了C P U時間,並且可以訪問記憶體塊。注意,這3個執行緒都以只讀方式訪問記憶體。這就是所有 3個執行緒能夠同時執行的唯一原因。還要注意,如何計算機上配有多個C P U,那麼所有3個執行緒都能夠真正地同時執行,從而可以在很短的時間內完成大量的操作。

    如果你使用自動重置的事件而不是人工重置的事件,那麼應用程式的行為特性就有很大的差別。當主執行緒呼叫S e t E v e n t之後,系統只允許一個輔助執行緒變成可排程狀態。同樣,也無法保證系統將使哪個執行緒變為可排程狀態。其餘兩個輔助執行緒將繼續等待。

    已經變為可排程狀態的執行緒擁有對記憶體塊的獨佔訪問權。讓我們重新編寫執行緒的函式,使得每個函式在返回前呼叫S e t E v e n t函式(就像Wi n M a i n函式所做的那樣) 。這些執行緒函式現在變成下面的形式:

 

    當執行緒完成它對資料的專門傳遞時,它就呼叫 S e t E v e n t函式,該函式允許系統使得兩個正在等待的執行緒中的一個成為可排程執行緒。同樣,我們不知道系統將選擇哪個執行緒作為可排程執行緒,但是該執行緒將進行它自己的對記憶體塊的專門傳遞。當該執行緒完成操作時,它也將呼叫S e t E v e n t函式,使第三個即最後一個執行緒進行它自己的對記憶體塊的傳遞。注意,當使用自動重置事件時,如果每個輔助執行緒均以讀 /寫方式訪問記憶體塊,那麼就不會產生任何問題,這些執行緒將不再被要求將資料視為只讀資料。這個例子清楚地展示出使用人工重置事件與自動重置事之間的差別。

    為了完整起見,下面再介紹一個可以用於事件的函式:

    BOOL PulseEvent(HANDLE hEvent);

    P u l s e E v e n t函式使得事件變為已通知狀態,然後立即又變為未通知狀態,這就像在呼叫S e t E v e n t後又立即呼叫R e s e t E v e n t函式一樣。如果在人工重置的事件上呼叫P u l s e E v e n t函式,那麼在發出該事件時,等待該事件的任何一個執行緒或所有執行緒將變為可排程執行緒。如果在自動重置事件上呼叫P u l s e E v e n t函式,那麼只有一個等待該事件的執行緒變為可排程執行緒。如果在發出事件時沒有任何執行緒在等待該事件,那麼將不起任何作用。

    P u l s e E v e n t函式並不非常有用。實際上我在自己的應用程式中從未使用它,因為根本不知道什麼執行緒將會看到事件的發出並變成可排程執行緒。由於在呼叫 P u l s e E v e n t時無法知道任何執行緒的狀態,因此該函式並不那麼有用。我相信在有些情況下,雖然 P u l s e E v e n t函式可以方便地供你使用,但是你根本想不起要去使用它。關於 P u l s e E v e n t函式的比較詳細的說明,請參見本章後面對S i n g l e O b j e c t A n d Wa i t函式的介紹。

相關推薦

Windows核心程式設計 執行核心物件同步()

第9章 執行緒與核心物件的同步     上一章介紹瞭如何使用允許執行緒保留在使用者方式中的機制來實現執行緒同步的方法。使用者方式同步的優點是它的同步速度非常快。如果強調執行緒的執行速度,那麼首先應該確

Windows核心程式設計 執行的排程、優先順序和親緣性(下)

7.6 運用結構環境     現在應該懂得環境結構線上程排程中所起的重要作用了。環境結構使得系統能夠記住執行緒的狀態,這樣,當下次執行緒擁有可以執行的C P U時,它就能夠找到它上次中斷執行的地方。

Python核心程式設計 練習

筆者剛剛開始Python的系統學習,所以在程式碼上還無法達到pythonic的水準,很多寫法也都是按照C++的習慣來寫的,希望能有前輩進行交流指導。 歡迎拍磚 9_1 #!/usr/bin/python2 # coding: utf-8 if

J2SE——執行(常用方法)

3 狀態轉換          建立執行緒物件 new--> 執行緒啟動,進入就緒狀態 start() 等CPU空閒          ---->run()方法真正開始執行 ----> 阻塞執行緒,繼續進入就緒(準備)狀態          ---->

2 執行鎖-2.3 超越內建鎖

內建鎖的缺點: 一個執行緒因為等待內建鎖而進入阻塞之後,就無法中斷該執行緒了; 嘗試獲得內建鎖時,無法設定超時; 獲得內建鎖,必須使用synchronized塊; synchronized其實是一個語法糖,等價於 synchronized(this

VisualBasic程式設計的學習自測

一、本章知識點分析 1.程式錯誤的分類   程式中的錯誤大體可分為三類:即編譯錯誤、實時錯誤和邏輯錯誤。   編譯錯誤多數是因為不正確的程式碼產生的,即在編寫程式時書寫了錯誤的語法,從而導致VB編譯器無法正確解釋原始碼而產生的錯誤,因此也稱為語法錯誤。

C++11多執行程式設計 : std::async 更更優雅的寫多執行

C++11 Multithreading – Part 9: std::async Tutorial & Example Varun May 5, 2017 C++11 Multithreading – Part 9: std::async Tutorial &

【Java多執行程式設計核心技術】 執行間通訊

等待/通知機制 public final native void wait(long timeout) throws InterruptedException; /* @throws IllegalMonitorStateException if the current th

執行、對稱多處理和微核心【計算機作業系統】

4.1 表3.5列出了在一個沒有執行緒的作業系統中程序控制塊的基本元素。對於多執行緒系統,這些元素中那些可能屬於執行緒控制塊,那些可能屬於程序控制塊? 這對於不同的系統來說通常是不同的,但一般來說,程序是資源的所有者,而每個執行緒都有它自己的執行狀態。關於表3.5中的每一項的一些結論如

C++11多執行程式設計 : 使用packaged_task優雅的讓同步函式非同步執行

C++11 Multithreading – Part 10: packaged_task<> Example and Tutorial Varun July 2, 2017 C++11 Multithreading – Part 10: packaged_tas

《Java 7併發程式設計實戰手冊》執行執行

感謝人民郵電大學授權併發網釋出此書樣章,新書購買傳送門=》噹噹網 本章將介紹下列內容: 建立執行緒執行器 建立固定大小的執行緒執行器 在執行器中執行任務並返回結果 執行多個任務並處理第一個結果 執行多個任務並處理所有結果 在執行器中延時執行任務 在執行器中週期性執行任務 在執行器中取消任務

Windows高階程式設計執行核心物件同步

使用者方式同步的優點是它的同步速度非常快。如果強調執行緒的執行速度,那麼首先應該確定使用者方式的執行緒同步機制是否適合需要。使用者方式執行緒同步機制的侷限性:1、互鎖函式家族只能在單值上執行2、關鍵程式碼段只能對單個程序中的執行緒實施同步3、關鍵程式碼段容易陷入死鎖狀態,因為

Java併發程式設計從入門到精通 之 執行安全的集合類

java.util.HashTable:-1 說明:Hashtable函式均為同步,是執行緒安全,key,value均不能為null。-2 基本方法:get(), put(), remove(), clear(), putAll(), contains(),containsK

JavaSE習題 執行(未完成)

問答題 1.執行緒和程序是什麼關係?   程序是程式的一次動態執行,對應了從程式碼載入,執行至執行完畢的一個完整的過程   執行緒是比程序更小的執行單位,一個程序在其執行過程中可以產生多個執行緒,形成多條執行線索 2.執行緒有幾種狀態?   4種,新建,執行,中斷,死亡 3.引起執行緒中斷的常見原

RTthread學習筆記————4 執行管理

什麼是執行緒 執行緒,有時被稱為輕量級程序(Lightweight Process,LWP),是程式執行流的最小單元。一個標準的執行緒由執行緒ID,當前指令指標(PC),暫存器集合和堆疊組成。 RT-Thread 的執行緒排程器是搶佔式的,主要的工作

12 執行控制

請移步到這: 12.2 執行緒限制 12.3 執行緒屬性 執行緒具有一系列屬性,這些屬性可以線上程建立的時候指定。 只需要建立並填充一個 pthrea_attr t型別的執行緒屬性物件ATTR, 並將其作為第二個引數傳遞給pthread create就可

python核心程式設計

6-1 字串。string模組中是否有一種字串方法或者函式可以鑑定一個字串是否是另一個大字串的一部分? #in/not in 可以判斷一個字串是否再另一個字串中 'bc' in 'abcd' Out[3

[讀書筆記][Java併發程式設計實戰]第二 執行安全性

                                          第二章 執行緒安全性 1-什麼是執行緒安全的類? 當多個執行緒訪問某一個類時,不管執行時環境採用何種排程方式或者這些執行緒將如何交替執行,並且在主調程式碼中不需要任何額外的同步或協同,這個

組合語言程式設計

一、操作符offset 功能:取得標號的偏移地址。 格式:offset 標號 二、jmp指令 jmp為無條件轉移指令,可以只修改IP,也可以同時修改CS和IP。 需要給出兩種資訊:①轉移的目的地址。  ②轉移的距離(段間轉移、段內短轉移、段內近轉移) 三、依據位移進行轉移的jmp指令

-執行同步工具(引言)

宣告:本文是《 Java 7 Concurrency Cookbook 》的第三章, 作者: Javier Fernández González 譯者:鄭玉婷 3 執行緒同步工具 章節提要: 併發地訪問資源的控制 併發地訪問多個副本資源的控制 等待多個併發事件 在一個相同點同步任務 併發的階