不同級別併發理解

2021-08-10 08:20:27 字數 2553 閱讀 9559

毫無疑問,stackless python幾乎有匪夷所思的併發效能,比其他方案快上幾十倍,而且借助stackless python提供的channel機制,實現也相當簡單。也許這個結果向我們部分揭示了沈仙人基於stackless python實現的eurasia3能夠提供相當於c語言效果的恐怖併發效能的原因。

4.2  python執行緒

從道理上來講,thread模組似乎應該和threading提供基本相同的效能,畢竟threading只是對thread的一種封裝嘛,後台機制應該是一致的。或許threading由於本身類例項維護方面的開銷,應該會比直接用thread慢一點。從實驗結果來看,二者效能也確實差不多。只是不大明白為何threading方案的測試結果不是很穩定,即使對其他方案的測試執行多次,誤差也不會像threading這麼飄。從**實現體驗來說,用threading配合queue比直接用thread實在是輕鬆太多了,並且出錯的機會也要少很多。

4.3  python程序

processing模組給出的程序方案大致比thread執行緒要慢一倍,並且這是在我特意調整虛擬機器給它預備了足夠空閒記憶體、避免使用交換分割槽的情況下取得的(特意分給虛擬機器700多m記憶體就是為了這個)。而其他方案僅僅占用數m記憶體,完全無需特意調大可用記憶體總量。當然,如果給虛擬機器多啟用幾個核心的話,processing也許會佔上點便宜,畢竟目前thread模組是不能有效利用多cpu資源的(經實驗,stackless python在開啟雙核的情況下表現的效能和單核是一樣的,說明也是不能有效利用多cpu)。因此一種比較合理的做法是根據cpu的數量,啟用少量幾個程序,而在程序內部再開啟執行緒進行實際業務處理,這也是目前python社群推薦的有效利用多cpu資源的辦法。好在processing配合其自身提供的queue模組,程式設計體驗還是比較輕鬆的。

4.4  greenlet超輕量級方案

基於greenlet的實現則效能僅次於stackless python,大致比stackless python慢一倍,比其他方案快接近乙個數量級。其實greenlet不是一種真正的併發機制,而是在同一執行緒內,在不同函式的執行**塊之間切換,實施「你執行一會、我執行一會」,並且在進行切換時必須指定何時切換以及切換到哪。greenlet的介面是比較簡單易用的,但是使用greenlet時的思考方式與其他併發方案存在一定區別。執行緒/程序模型在大邏輯上通常從併發角度開始考慮,把能夠並行處理的並且值得並行處理的任務分離出來,在不同的執行緒/程序下執行,然後考慮分離過程可能造成哪些互斥、衝突問題,將互斥的資源加鎖保護來保證併發處理的正確性。greenlet則是要求從避免阻塞的角度來進行開發,當出現阻塞時,就顯式切換到另一段沒有被阻塞的**段執行,直到原先的阻塞狀況消失以後,再人工切換回原來的**段繼續處理。因此,greenlet本質是一種合理安排了的序列,實驗中greenlet方案能夠得到比較好的效能表現,主要也是因為通過合理的**執行流程切換,完全避免了死鎖和阻塞等情況(執行帶螢幕輸出的ring_greenlet.py我們會看到指令碼總是乙個乙個地處理訊息,把乙個訊息在環上從頭傳到尾之後,再開始處理下乙個訊息)。因為greenlet本質是序列,因此在沒有進行顯式切換時,**的其他部分是無法被執行到的,如果要避免**長時間占用運算資源造成程式假死,那麼還是要將greenlet與執行緒/程序機制結合使用(每個執行緒、程序下都可以建立多個greenlet,但是跨執行緒/程序時greenlet之間無法切換或通訊)。

stackless則比較特別,對很多資源從底層進行了併發改造,並且提供了channel等更適合「併發」的通訊機制實現,使得資源互斥衝突的可能性大大減小,併發效能自然得以提高。粗糙來講,greenlet是「阻塞了我就先乾點兒別的,但是程式設計師得明確告訴greenlet能先乾點兒啥以及什麼時候回來」;stackless則是「東西我已經改造好了,你只要用我的東西,併發衝突就不用操心,只管放心大膽地併發好了」。greenlet應該是學習了stackless的上下文切換機制,但是對底層資源沒有進行適合併發的改造。並且實際上greenlet也沒有必要改造底層資源的併發性,因為它本質是序列的單執行緒,不與其他併發模型混合使用的話是無法造成對資源的併發訪問的。

greenlet 封裝後的 eventlet 方案

eventlet 是基於 greenlet 實現的面向網路應用的併發處理框架,提供「執行緒」池、佇列等與其他 python 執行緒、程序模型非常相似的 api,並且提供了對 python 發行版自帶庫及其他模組的超輕量併發適應性調整方法,比直接使用 greenlet 要方便得多。並且這個解決方案源自著名虛擬實境遊戲「第二人生」,可以說是久經考驗的新興併發處理模型。其基本原理是調整 python 的 socket 呼叫,當發生阻塞時則切換到其他 greenlet 執行,這樣來保證資源的有效利用。需要注意的是:

在效能測試結果方面,eventlet 消耗的執行時間大致是 greenlet 方案的 3 到 5 倍,而 python 標準執行緒模型的 thread 方式消耗的執行時間大致是 eventlet 測試**的 8 到 10 倍。其中前者可能是因為我們在 eventlet 的測試**中,使用佇列機制來完成所有的訊息傳遞,而佇列上的訪問互斥保護可能額外消耗了一些運算資源。總體而言,eventlet 模型的併發效能雖然比 stackless python 和直接使用 greenlet 有一定差距,但仍然比標準執行緒模型有大約乙個數量級的優勢,這也就不奇怪近期很多強調併發效能的網路伺服器實現採取 eventlet 、執行緒、程序三者組合使用的實現方案。

CMMI不同級別

ml1初始級,軟體過程是無序的,有時候甚至是混亂的,對過程幾乎沒有定義,成功取決於個人努力。管理是反應式的。ml2已管理級,建立了基本的專案管理過程來跟蹤費用 進度和功能特性。制定了必要的過程紀律,能重複早先類應用專案的成功經驗。ml3已定義級,已將軟體管理和工程兩個方面的過程文件化 標準化,並綜合...

CMMI不同級別

ml1初始級,軟體過程是無序的,有時候甚至是混亂的,對過程幾乎沒有定義,成功取決於個人努力。管理是反應式的。ml2已管理級,建立了基本的專案管理過程來跟蹤費用 進度和功能特性。制定了必要的過程紀律,能重複早先類應用專案的成功經驗。ml3已定義級,已將軟體管理和工程兩個方面的過程文件化 標準化,並綜合...

對不同隔離級別的理解

以下是我個人的理解,有不對的地方,還望博友指出哈。在資料庫中,有4種不同的隔離級別供我們選擇,分別是read uncommited,read commited,repeatable read,serializable。我來依依解釋這四種級別 第乙個,read uncommited,從名字上看,說的是...