windows核心編程–纖程

來源:互聯網
上載者:User
比線程更小的單位,好像用的不多的哦

纖程的操作

首先要注意的一個問題是,實現線程的是Wi n d o w s核心。作業系統清楚地知道線程的情況,並且根據M i c r o s o f t定義的演算法對線程進行調度。纖程是以使用者方式代碼來實現的,核心並不知道纖程,並且它們是根據使用者定義的演算法來調度的。由於你定義了纖程的調度演算法,因此,就核心而言,纖程採用非搶佔式調度方式。

需要瞭解的下一個問題是,單線程可以包含一個或多個纖程。就核心而言,線程是搶佔調度的,是正在執行的代碼。然而,線程每次執行一個纖程的代碼—你決定究竟執行哪個纖程(隨著我們講解的深入,這些概念將會越來越清楚)。

當使用纖程時,你必須執行的第一步操作是將現有的線程轉換成一個纖程。可以通過調用C o n v e r t T h r e a d To F i b e r函數來執行這項操作:

 

PVOID ConvertThreadToFiber(PVOID pvParam);

該函數為纖程的執行環境分配相應的記憶體(約為2 0 0位元組)。該執行環境由下列元素組成:

• 一個使用者定義的值,它被初始化為傳遞給C o n v e r t T h r e a d To F i b e r的p v P a r a m參數的值。 

• 結構化異常處理鏈的頭。 

• 纖程記憶體棧的最高和最低地址(當將線程轉換成纖程時,這也是線程的記憶體棧)。 

• CPU寄存器,包括堆棧指標、指令指標和其他。

當對纖程的執行環境進行分配和初始化後,就可以將執行環境的地址與線程關聯起來。該線程被轉換成一個纖程,而纖程則在該線程上運行。C o n v e r t T h r e a d To F i b e r函數實際上返回纖程的執行環境的記憶體位址。雖然必須在晚些時候使用該地址,但是決不應該自己對該執行環境資料進行讀寫操作,因為必要時纖程函數會為你對該結構的內容進行操作。現在,如果你的纖程(線程)返回或調用E x i t T h r e a d函數,那麼纖程和線程都會終止運行。

除非打算建立更多的纖程以便在同一個線程上運行,否則沒有理由將線程轉換成纖程。若要建立另一個纖程,該線程(當前正在運行纖程的線程)可以調用C r e a t e F i b e r函數:

 

PVOID CreateFiber(   DWORD dwStackSize,   PFIBER_START_ROUTINE pfnStartAddress,   PVOID pvParam);

C r e a t e F i b e r首先設法建立一個新記憶體棧,它的大小由d w S t a c k S i z e參數來指明。通常傳遞的參數是0,按照預設設定,它建立一個記憶體棧,其大小可以擴充為1 M B,不過開始時有兩個儲存空間頁面用於該記憶體棧。如果設定一個非0值,那麼就用設定的大小來儲存和使用記憶體棧。

接著,C r e a t e F i b e r函數分配一個新的纖程執行環境結構,並對它進行初始化。該使用者定義的值被設定為傳遞給C r e a t e F i b e r的p v P a r a m參數的值,新記憶體棧的最高和最低地址被儲存,同時,纖程函數的記憶體位址(作為p f n S t a r t A d d r e s s參數來傳遞)也被儲存。

P f n S t a r t A d d r e s s參數用於設定必須實現的纖程常式的地址,它必須採用下面的原型:

 

VOID WINAPI FiberFunc(PVOID pvParam);

當纖程被初次調度時,該函數就開始運行,並且將原先傳遞給C r e a t e F i b e r的p v P a r a m的值傳遞給它。可以在這個纖程函數中執行想執行的任何操作。但是該函數的原型規定傳回值是V O I D,這並不是因為傳回值沒有任何意義,而是因為該函數根本不應該返回。如果纖程確實返回了,那麼線程和該線程建立的所有纖程將立即被撤消。

與C o n v e r t T h r e a d To F i b e r函數一樣,C r e a t e F i b e r函數也返回纖程運行環境的記憶體位址。但是,與C o n v e r t T h r e a d To F i b e r不同的是,這個新纖程並不執行,因為當前啟動並執行纖程仍然在執行。在單個線程上,每次只能運行一個纖程。若要使新纖程能夠運行,可以調用Switch To Fiber函數:

 

VOID SwitchToFiber(PVOID pvFiberExecutionContext);

Switch To Fiber 函數只有一個參數,即p v F i b e r E x e c u t i o n C o n t e x t,它是上次調用C o n v e r t T h r e a d To F i b e r或C r e a t e F i b e r函數時返回的纖程的執行環境的記憶體位址。該記憶體位址告訴該函數要對哪個纖程進行調度。S w i t c h To F i b e r函數在內部執行下列操作步驟:

1) 它負責將某些當前的C P U寄存器儲存在當前啟動並執行纖程執行環境中,包括指令指標寄存器和堆棧指標寄存器。

2) 它將上一次儲存在即將啟動並執行纖程的執行環境中的寄存器裝入C P U寄存器。這些寄存器包括堆棧指標寄存器。這樣,當線程繼續執行時,就可以使用該纖程的記憶體棧。

3) 它將纖程的執行環境與線程關聯起來,線程運行特定的纖程。

4) 它將線程的指令指標設定為已儲存的指令指標。線程(纖程)從該纖程上次執行的地方開始繼續執行。

S w i t c h To F i b e r函數是纖程獲得C P U時間的唯一途徑。由於你的代碼必須在相應的時間顯式調用S w i t c h To F i b e r函數,因此你對纖程的調度可以實施全面的控制。記住,纖程的調度與線程調度毫不相干。纖程運行所依賴的線程始終都可以由作業系統終止其運行。當線程被調度時,當前選定的纖程開始運行,而其他纖程則不能運行,除非顯式調用S w i t c h To F i b e r函數。若要撤消纖程,可以調用D e l e t e F i b e r函數:

 

VOID DeleteFiber(PVOID pvFiberExecutionContext);

該函數用於刪除p v F i b e r E x e c u t i o n C o n t e x t參數指明的纖程,當然這是纖程的執行環境的地址。該函數能夠釋放纖程棧使用的記憶體,然後撤消纖程的執行環境。但是,如果傳遞了當前與線程相關聯的纖程地址,那麼該函數就在內部調用E x i t T h r e a d函數,該線程及其建立的所有纖程全部被撤消。

D e l e t e F i b e r函數通常由一個纖程調用,以便刪除另一個纖程。已經刪除的纖程的記憶體棧將被撤消,纖程的執行環境被釋放。注意,纖程與線程之間的差別在於,線程通常通過調用E x i t T h r e a d函數將自己撤消。實際上,用一個線程調用Te r m i n a t e T h r e a d函數來終止另一個線程的運行,是一種不好的方法。如果你確實調用了Te r m i n a t e T h r e a d函數,系統並不撤消已經終止啟動並執行線程的記憶體棧。可以利用纖程的這種能力來刪除另一個纖程,後面介紹應用程式範例時將說明這是如何?的。

為了使操作更加方便,還可以使用另外兩個纖程函數。一個線程每次可以執行一個纖程,作業系統始終都知道當前哪個纖程與該線程相關聯。如果想要獲得當前啟動並執行纖程的執行環境的地址,可以調用G e t C u r r e n t F i b e r函數:

 

PVOID GetCurrentFiber();

另一個使用非常方便的函數是G e t F i b e r D a t a:

 

PVOID GetFiberData();

前面講過,每個纖程的執行環境包含一個使用者定義的值。這個值使用作為C o n v e r t T h r e a dTo F i b e r或C r e a t e F i b e r的p v P a r a m參數而傳遞的值進行初始化。該值也可以作為纖程函數的參數來傳遞。G e t F i b e r D a t a只是查看當前執行的纖程的執行環境,並返回儲存的值。

無論G e t C u r r e n t F i b e r還是G e t F i b e r D a t a,運行速度都很快,並且通常是作為內蘊函數(infrinsic funcfion)來實現的,這意味著編譯器能夠為這些函數產生內聯代碼。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.