WinCE多線程事半功倍 但須避免資源爭奪

來源:互聯網
上載者:User

 【IT168 專稿】WinCE系統是一個多任務的作業系統。一般來說,實現多任務的方法是採用多線程和多進程機制。因此掌握多進程和多線程的技巧和方法,對於編寫複雜的WinCE嵌入式程式是必須的。因為多線程編程方法能有效地解決各種並行的複雜工作任務,使一些特別複雜的總體設計和解決方案變得更簡潔和更清晰。

  近期,我在一個嵌入式開發項目中就體驗到輕視多線程的慘痛教訓。由於在開發過程中對多線程沒有處理好,結果是經常會出現線程爭奪資源,使系統變得緩慢或直接癱瘓,這些難以察覺的多執行緒錯誤使到項目群組成員被迫花了許多額外的時間來處理。不但項目開發進度嚴重滯後,而且還影響到產品的上市時間。在WinCE編程中,其實多執行緒並不象表面看起來的那麼簡單。本文分享我在此項目得到的一些關於多線程的經驗和教訓。

  一. 多線程中最常見的兩類資源爭奪問題

  一個嵌入式系統開發一般來說有兩種編程方式:一是核心態編程,另一種是使用者態編程。當一個進程執行系統調用而陷入核心執行時,稱為進程處於核心態,此時CPU處於特權級最高的核心執行過程。當進程在執行使用者自己的代碼時,則稱為處於使用者態,此時CPU在特權級最低的使用者代碼中運行。在核心態下的CPU可執行任何指令,在使用者態下的CPU只能執行非特權指令,使用者態的程式不能隨意操作核心地址空間。所以,多線程資源衝突在核心編程中遠比使用者態程式的編程要常見。

  在這次嵌入式項目中,由於依仗WinCE核心是由我們項目組自已定製和剪裁的,許多項目成員為了讓程式的執行效率更高、代碼更短,不但經常把進程陷入到核心運行態中執行,而且還過份的強調利用多線程來提高執行效率。結果是不但沒有提高程式執行效率,反而使到WinCE系統經常出現資源爭奪情況。輕則運行緩慢,重則死結和死機。我們總結這次開發失敗的經驗教訓是:多線程編程能讓開發事半功倍,但一定要注意多線程資源爭奪的安全性。這是一個開發人員如何做到“魚與熊掌”兩者平衡兼得的考驗問題。

  (1)多線程資源衝突問題

  WinCE系統支援多線程,這無疑是一件很好的事情。但這同時也帶來了另一個比較棘手的設計問題,那就是如何讓多線程的資源爭奪是安全的,這是非常重要的。一般的說,多線程的資源安全性是指一個線程在被調用過程中,還未返回時又再次被其它線程調用的情況下執行結果的可靠性。如果結果是可靠的,則稱這個多安全執行緒的;如果結果是不可靠的,則稱這個多線程是不安全的,原因是發生了多線程資源衝突問題。因此,多線程資源安全性如果處理不當,輕則導致程式運行時出錯,嚴重的話將導致系統崩潰。

  (2)多線程死結問題

  從以上第一點我們可知,在WinCE多線程編程中防止線程資源衝突是極為重要的。因此,這個項目開發過程中我們大量通過鎖定一個資源來防止任何其它線程訪問這個資源,以避免資源競爭。但沒有想到的是,這又導致了多線程資源爭奪的另一個常見問題:死結。結果在項目測試時,我們遇到的最常見的現象就是多線程因資源競爭不當而產生死結的現象,後來需要逐一分析資源死結的過程,這讓我們開發組的各成員都備受折磨和感到痛苦不堪。

  所謂死結(Dead Lock)是指在WinCE編程中兩個或兩個以上的並發進程在執行過程中,如果每個進程持有某種資源而又都在等待別的進程釋放它們現在保持著的資源,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法進行下去。此時稱系統處於死結狀態或系統產生了死結,這些永遠在互相等待的進程稱為死結進程。

 

    二. 為什麼多線程會產生資源爭奪?

  進程、線程是WinCE核心最基本的服務,也是核心最主要的組成部分。這兩方面的知識是一個WinCE嵌入式軟體開發人員必須掌握的基礎知識,只有掌握了這些知識,才能夠充分利用WinCE系統核心提供的服務。

  (1)什麼是多線程?

  在談到多線程資源安全性的時候,我們首先必須瞭解什麼是線程。WinCE是一個搶佔式多任務作業系統,搶佔多任務又稱為調度。多線程是這樣一種機制,它是指允許在程式中並發執行多個指令流,每個指令流都稱為一個線程,彼此間互相獨立。每一個線程都有五種狀態,分別為運行、掛起、睡眠、阻塞、終止。多線程是多任務的特殊形式,多線程是為了使得多個線程並行的工作以完成多項任務,以提高系統的效率。

  除了一些在運行中必不可少的資源(比如寄存器和棧等)外,線程本身並不佔有系統的資源。但是線程卻可以和同屬於一個進程的另一個線程共用進程所擁有的全部資源。同進程一樣,一個線程可以建立或者撤銷另一個線程,同一個進程內的線程也可以並發執行。從並發性的角度來看,不僅可以在不同的進程之間並發執行,在同一個進程中的多個線程之間也是可以並發執行的。因此,這種方式可以使WinCE系統具有更好的並發執行能力,可以更為有效利用系統資源,同時在一定程度上也極大的提高了系統的運行效率。

  (2)多線程資源爭奪起源於同步與競爭

  在WinCE多線程共用資源中,防止存取違規是極為重要的。正常來說,被允許執行的線程首先會擁有對變數或對象的排他性訪問權。當第一個線程訪問對象時,第一個線程會給訪問對象加鎖,而這個鎖會導致其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。在WinCE系統中,如果一個線程不能得到需要的某個資源,它將掛起執行(阻塞),直到該資源有效為止。所以,在WinCE系統運行過程中,各線程都將會對資源進行鎖定或解鎖。

  因此,從上可知線上程之間要相互連信、相互協調才能完成任務。例如,當有多個線程共同訪問同一個資源時,就必須保證第一個線程在正讀取這個資源資料的時候,其它線程不能夠修改它,這就需要線程之間相互連信。再有當一個線程要準備執行下一個任務之前,它必須等待另一個線程終止才能運行,這也需要彼此相互連信。一般在使用者態模式下的同步方法有:互鎖函數Interlocked(屬原子訪問),臨界區Critical Section(保證臨界區內的資源不被其它線程訪問)。在核心模式下的同步方法有:事件對象Event(線程睡眠,而核心執行等待),互斥對象Mutex(類似於臨界區,但相對較慢),信標對象Semaphore(用於限制資源訪問數量),訊息佇列MsgQueue(利用很小的記憶體傳遞訊息)等。

 

 

   三. 如何避免多線程出現爭奪資源問題?

  多線程執行是WinCE系統的特點之一,我們在編程時應該要大力的利用,以提高程式的執行效率。但是也必須要小心處理多線程問題,避免出現多線程爭奪資源。一般來說,針對不同的情況有不同的處理方式,主要分為以下兩種情況:

  (1)建立同步機制,避免進程互斥競爭

  在正常情況下,一個進程的運行一般是不會影響到其它正在啟動並執行進程的。但是對於某些有特殊要求的,如需要以獨佔資源的進程(或線程)就要求在其進程運行期間不允許其它進程試圖使用此資源,這就引出了進程互斥競爭的問題。要實現進程互斥的核心思想比較簡單:進程在啟動時首先檢查當前系統是否已經存在有此進程的執行個體,如果沒有,進程將成功建立並設定標識執行個體已經存在的標記。此後再建立進程時將會通過該標記而知曉其執行個體已經存在,從而保證進程在系統中只能存在一個執行個體。具體可以採取記憶體映像檔案、有名事件量、有名互斥量以及全域共用變數等多種方法來實現。

  一般來說,使用臨界區、互斥、訊號量和事件可解決線程同步的問題。這裡介紹兩種最常用的方法:①臨界區:它是一種最直接的線程同步方式。所謂臨界區,就是一次只能由一個線程來執行的一段代碼。如把初始化數組的代碼放在臨界區內,另一個線程在第一個線程處理完之前是不會被執行的。②互斥機制:互斥非常類似於臨界區,但有兩個關鍵的區別:首先,互斥可用於跨進程的線程同步。其次,互斥能被賦予一個字串名字,並且能通過引用此名字建立現有互斥對象的附加控制代碼。

  另外,還需要提醒的是臨界區與事件對象的最大的區別是在效能上。臨界區在沒有線程衝突時,一般要用到10-15個時間片,而事件對象由於涉及到系統核心則要到用400-600時間片。所以,臨界區是一個進程裡的所有線程同步的最好辦法,因為它不是系統級的,只是進程級的。

  (2)建立資源分派圖,避免進程死結

  一般來說,多線程產生死結是與進程對資源的需求、進程的執行速度、資源的分配策略有關。因此,如果無法通過設計來避免死結,則應該建立資源分派圖。通過仔細跟蹤系統中的所有線程和它們鎖定的共用資源,周期性地進行檢查和維護資源分派圖,及時發現迴圈等待的特徵,從而事先識別潛在死結。

  建立資源分派圖需要識別每個受保護的共用資源,以及指向其中某一資源的所有線程。一般可以採用這幾個步驟來實現:①識別所有可能阻塞的系統調用,因為每個受保護的共用資源總是有一些與訪問它有關的阻塞調用。②識別出擷取共用資源的阻塞調用之後,在原始碼中尋找它們的各次調用情況。③對於每次調用,記錄下指向資源的線程名稱和該資源的名稱。通常調用本身將受保護的資源作為一個參數來傳遞,通過這種方式可以識別出所有受保護的資源以及分配資源的線程。④建立資源分派圖,並檢查是否有任何資源存在迴圈路徑。

  當然,如果預先確定每一個共用資源並建立分配圖是不實際或不可能的,此時可以增加一些額外的代碼,以便在系統運行時檢測出潛在的死結。例如目前有許多不同的演算法都致力於最佳化這個檢測過程,但本質上它們還是動態地建立某種資源分派圖。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.