1. 程式人生 > >為什麼當前大多數應用程式是多執行緒的,為什麼要使用支援多執行緒的庫

為什麼當前大多數應用程式是多執行緒的,為什麼要使用支援多執行緒的庫

原文

http://www.nynaeve.net/?p=198
        大部分的Win32 程式在執行的時候,其程序中至少有一段時間是超過一個執行緒的,儘管有時程式沒有明確的建立一個執行緒。這是因為有些系統API 會為了它們自己的目的而建立執行緒。
        例如,控制檯Ctrl-C/Ctrl-Break 事件預設情況下是被單獨的執行緒處理的。(在內部,CSRSS在容器程序中建立一個新執行緒,該執行緒之後呼叫kernel32 的函式來呼叫活動控制檯的處理列表。這也是kernel32必須在所有的程序中有同樣的基地址的一個原因,另外,CSRSS 快取kernel32中Ctrl-C 的分發函式並假設它在所有的客戶程序中的地址是一樣的。)這可能會導致潛在的意外執行緒問題,這取決於控制檯控制處理程式所進行的操作。例如,如果一個控制檯控制程式向控制檯輸出,除非顯式使用一些形式的同步方法,否則這個輸出行為將不會與在此控制檯上執行的內部執行緒的任何I/O 操作進行同步。
        這也是現在的VS 編譯器完全避開單執行緒CRT 的原因,作為替代品,其支援CRT的多執行緒變體。對於遊戲來說,為了節省極少的鎖定開銷而使用一個單執行緒CRT 可以獲得的好處是有限的,因為執行緒可能因為奇怪的原因而終止執行(比如一個控制檯控制處理器的註冊操作)。在一個主要是單執行緒的程式中, 臨界區程式碼的執行速度足夠快,與正在執行的實際處理開銷相比,CRT 鎖所產生的任何開銷都是微不足道的。
        Win32 API的很大一部分是通過使用工作執行緒來完成任務的,儘管這些執行緒對於程序映象來說有有限的可見性。例如, WSAAsyncGetHostByName 使用一個工作執行緒來同步呼叫 gethostbyname 並通過一個Windows 訊息將結果傳送給請求者。甚至除錯程式也將導致在被除錯程序中生成一個執行緒以滿足偵錯程式的侵入過程。
        由於大部分的Win32程式或多或少都會遇見多執行緒的情況,除了CRT,Win32的其它元件也漸漸放棄了對於純單執行緒操作最後的支援。例如, low fragmentation heap (LFH) 不再支援 HEAP_NO_SERIALIZE,該標誌使得堆的內建臨界區不可用。這種情況下,就像CRT,完全不獲取鎖而安全的執行的情況是非常有限的,而這僅僅獲得了比較小的好處,不如承擔一下為了獲得臨界區鎖而呼叫的函式所帶來的開銷。(進入一個沒有被擁有的臨界區而不涉及到核心模式轉移的時候,其所消耗的時間是非常少的。在一個典型的單執行緒應用程式中,所有的臨界區幾乎都是被擁有的,或者因為遞迴呼叫而被執行緒擁有)