1. 程式人生 > >VB.net學習筆記(二十九)認識STA與MTA

VB.net學習筆記(二十九)認識STA與MTA

一、應用程式中的多執行緒
    VB5/6支援多執行緒,但支援的執行緒模式都是STA(單執行緒單元,Single Threaded Apartments)。

    .NET Framework中沒有單元的概念,它是在應用程式域中管理所有執行緒的。預設情況下,所有的.NET應用程式都是多執行緒的,它們可以在任一時間訪問所有的物件。故關注託管程式碼中的共享資源是值得的。

    .NET Framework支援託管的和非託管的執行緒,並支援所有的Win32執行緒模式。當您試圖從託管程式碼屮訪問COM元件時,傳統的COM元件將建立非託管執行緒。.NET Framework中的執行緒,無論是託管的還是非託管的,都是使用Thread物件建立的。

   Win32時的介面執行緒(UIT,User-Interface Threads)與使用者執行緒(Worker Threads),現在被叫作單元模式執行緒(AMT,Apartment Model Threading)與自由執行緒(FT,Free Threading)。.net中還被稱作單執行緒單元(STA,Single Threaded Apartment)或多執行緒單元(MTA,Multi Threaded Apartment)。

二、STA執行緒模式


    STA執行緒單元的執行方式稱為每客戶物件模式(Object-per-Client),即建立STA執行緒單元的程式碼擁有它自己的執行緒,在任何一個單元之內都只能有個執行緒。
                               
    (單元(Apartment)是一個邏輯容器,在相同上下文為共享執行緒的應用程式域內。程序啟用後,建立的物件也將駐留在應用程式域,與之對應的上下文也被建立。)

    在STA中,對執行緒的所有呼叫都將被放置到一個佇列中,然後逐個地處理對執行緒的呼叫。因此,STA執行緒永遠不會同時執行多個方法。STA執行緒有自己的專有資料,它們不會線上程之間共享資料。這種特徵使這一執行緒模式非常安全,避免了資料的損壞和同步問題。然而,這種特徵也束縛了開發人員的手腳,產生了一定的效能損害,因為每當建立一個執行緒時,都要進行資料副本工作。

    執行緒親合性用於定義執行緒和建立執行緒的程式碼之間的關係。每當呼叫STA單元執行緒時,呼叫者和執行緒之間的呼叫將由AppDomain之中的上下文進行處理,並由上下文維持執行緒的親和性。

    如果要特別指定使用單元執行緒模式的話,使用Main()方法上的STAThreadAttribute屬性即可實現這一操作。(VS2015已經將STAThreadAttribute改寫為STAThread)

    <STAThread> Sub Main()
        '.....
    End Sub


    <MTAThread> Sub Main() ‘預設多執行緒,可不寫
        '.....
End Sub

三、MTA執行緒模式
    STA和MTA執行緒單元的最大不同在於,在相同的MTA單元中可以同時容納多個正在執行的執行緒,這些執行緒使用在單元中可用的所有共享資料。
                      

    1、如何設計執行緒
    首先明確,在單核中同一時刻只有一個程序獲得CPU。

                    

    併發在單核和多核都可存在,就是同一時間有多個可以執行的程序。並行是指同一時間多個程序在微觀上都在真正的執行,這就只有在多核的情況下了。

    擁有兩個或以上的多執行緒程式,無論是否使用並行,只要是併發就會顯著提升效能。

    併發執行緒執行意味著在同時間內有兩個或更多個執行緒處於執行之中。執行緒並行則是兩個或以上執行緒分別在不同的處理處理器上同時執行(上圖)。

     在開發應用程式之前,應該考慮下列問題:
         (1)應用程式是否需要專門分出執行緒來處理?
         (2)若需要執行緒,怎麼分,分出的準則是什麼?
         (3)主執行緒和工作者執行緒之間如何協調、如何控制?

    2、執行緒間的關係
    多執行緒應用程式中生成的執行緒之間可能存在關係,也可能不存在關係。它們主有三種情況:主執行緒和工作者執行緒模式、對等執行緒模式、管道執行緒模式。   

       (1)主執行緒和工作者執行緒模式
        這是最常見的模式。主執行緒接收所有的輸入,並將這些輸入傳遞給其他執行緒來執行某些任務。主執行緒需要等待工作者執行緒的結束,也可能不需要。在這種模式中,工作者執行緒不和輸入源發生互動作用,它們是從主執行緒中讀取資料來執行任務的。執行緒是完全相互獨立的,所有的執行緒完全受控於其父執行緒。
              

      (2)對等執行緒模式
      此模式下,每個執行緒都將從適當的來源接收其自己的輸入,並對輸入作出相應的處理。例如,UI執行緒將從鍵盤和滑鼠處接收輸入,並進行相應的處理。另一方面,Worker執行緒A將監聽特殊的套接字Socket,當發現有從套接字傳遞過來的輸入資訊時就作出相應的處理。同樣,Worker執行緒B將等待系統事件,並作出相應的處理。在這種模式中,所有的執行緒都將並行執行,不會產生阻塞和等待其他執行緒的情況。
                    

      (3)管道執行緒模式
        管道執行緒模式是基於一系列任務的,並且每個任務都依賴於前面的任務。例如,主執行緒建立了一系列執行緒,在前面的執行緒執行完畢之前,其他的所有執行緒都將等待。如果您的任務分成若干個階段,每個階段都依賴於前一階段任務,那麼這種型別的執行緒關係將顯示出其獨特的優點。