天天看點

同步異步線程程序的一些思考

 <b>同步與異步</b>

    同步與異步在生活中随處可見。同步和異步是描述不同僚件發生的依賴關系,同步是指這兩個事件的發生有一定的時間順序,異步是指這兩個事件的發生是互相獨立的。

    比如去食堂吃飯,你需要先去那餐具(事件A),然後去某個視窗前打飯(事件B),接着找到一個座位(事件C),最後開始享受食物(事件D)。事件A,B,C,D有一定的依賴關系,是以它們之間需要同步。處理器中的取指、譯碼、執行、寄存器回寫、存儲器回寫,各個子執行單元的動作也是同步的。在Unix的Shell下使用管道同時啟動多個程序,這些程序之間的執行也是同步的。用VHDL編寫一個簡單的可複位預置計數器,如果将複位信号開始後還要在判斷時鐘信号,那麼這個複位也是同步的。GCC編譯器在運作的時候調用不同的子產品(預處理、編譯、優化、連結)對代碼進行處理也是同步的。

    同步的事件之間需要通過信号來表示事件序列中的下一個動作可以開始了。對于上面的例子,餐具就是事件B的信号,飯就是事件C的信号等等。CPU中的取值子產品取到指令之後,會譯碼子產品發送一個信号,譯碼子產品執行完之後再給執行子產品發送信号等等。計算機中線程和程序之間的同步除了時間關系外,更側重于合作關系,因為多個線程負責完成一個大的任務。

     異步是指事件之間是獨立發生的,比如編寫的帶複位預置功能的計數器,如果複位信号和時鐘信号沒有任何關系的話,那麼這麼複位各種就是異步的。因為複位的操作是立即執行的,沒有任何等待。在shell下啟動指令的時候,在指令後面添加一個“&amp;”符号,這個新啟動的程式就會在一個新的程序中執行,和目前程序時異步運作的。一個文字應用程式可以一邊排版一邊列印,每排版100頁,就送到列印機列印,然後接着排版。這時,處理器和列印機是異步運作的。

     再舉一個例子,比如在公共汽車上睡過了頭,發現已經過了目的地了。如果司機好心,立即停車讓你下去,這就是異步的。如果司機一定要等到下一站到了,你才能下車,這就是同步的。

     在單處理器上,使用異步程式設計是提高應用程式響應性和效率的關鍵手段之一。當然,每個異步的事件都要完整的儲存自己運作所需要的所有狀态資訊。在同步事件序列中,這些狀态資訊,可能會從上一個事件或者下一個事件中得到。

     計算機的所有計算都是對現實世界的模拟,不管是發動機外形優化程式還是材料分析的有限元程式,或者是關系資料庫。同步異步也是對現實世界不斷運作的事物事件的互相關系的一種描述。同步是因為事物運動的因果關系,異步是因為事物運動的獨立性。

<b>線程和程序</b>

<b></b>

<b>     </b>線程模型是對程序模型的改進,使用線程模型可以提高系統的吞吐量。這是因為多個線程之間共享程序的所有資源。在配置了線程模型的系統中,獨立執行和排程的最小實體就不再是程序,而是線程了,程序僅僅成為容納線程、位址空間、檔案描述符、資料等等的容器了。

     線程的上下文切換速度要比程序快很多,線程本身也是一些狀态資訊的容器,不過和程序這個框相比,線程也就是一個杯子而已。它要記錄堆棧資訊,程式的執行位置,狀态寄存器資訊,通用寄存器資訊,線程辨別、互斥量、信号量等資訊。

     除了上下文切換速度以外,還有一個“切換後綜合征問題”。程序切換後,需要執行一個完全不同的程式,會導緻TLB失效,Cache失效,還有一些其他硬體級優化的寄存器的失效。這些會導緻剛切換進來的程序在開始執行的一段時間比較慢。而線程在這個問題上,所受到的影響就要小得多。

     除此之外,還有通信問題。各個線程通信的帶寬比程序要大得多。因為線程共享位址空間,一個線程使用malloc開辟的記憶體可以給另外一個線程直接使用(傳入指針)。而程序還要通過管道,隊列之類的系統級通信環境。這就有點類似區域網路和廣域網的差別了。

本文轉自hipercomer 51CTO部落格,原文連結:http://blog.51cto.com/hipercomer/907955