什麼是併發操做

併發是指多個執行單元同時、並行被執行,而併發的執行單位對於共享資源(硬件資源和軟件上的全局變量、靜態變量等)的訪問很容易致使競態(race conditions)linux

競態主要發生在以下幾種狀況:安全

一、對稱多處理器(SMP)的多個CPU併發

二、單CPU內進程與搶佔它的進程函數

三、中斷(硬中斷、軟中斷、Tasklet、底半部)與進程之間測試

四、中斷也可能被更高優先級的中斷打斷,所以,多箇中斷之間也可能引發併發致使競態spa

解決競態問題的途徑是保證對共享資源的互斥訪問,所謂互斥訪問是指一個執行單元在訪問共享資源的時候,其餘的執行單元被禁止訪問。遞歸

訪問共享資源的代碼區成爲臨界區,臨界區須要被以某種互斥機制加以保護,中斷屏蔽、原子操做、自旋鎖和信號量是linux設備驅動中可採用的互斥途徑。進程

 

一、中斷屏蔽:只能禁止和使能本CPU內的中斷。資源

二、原子操做:是指在執行過程當中不會被別的代碼路徑所中斷的操做。內核代碼能夠安全的調用它們而不被打斷。分爲針對位和整形變量進行原子操做兩類同步

三、自旋鎖:理解它最簡單的方法是把它看成一個變量看待,該變量把一個臨界區標記爲」我當前在運行,請稍等一會「或者標記爲」我當前不在運行,能夠被使用「

           使用自旋鎖能夠保證臨界區不受別的CPU和本CPU內的搶佔進程打擾,可是獲得鎖的代碼路徑在執行臨界區的時候,還可能受到中斷和底半部的影響。

           爲防止這種影響,須要用到自旋鎖的衍生。能夠避免突如其來的中斷對系統形成的傷害。

           使用自旋鎖需注意以下:

           一、其實是忙等鎖,當鎖不可用時,CPU一直循環執行」測試並設置「該鎖直到可用而取得該鎖,CPU在等待自旋鎖時不作任何有用的工做,僅僅是等待。

               所以,只有在佔有鎖的時間極短的狀況下,使用自旋鎖纔是合理的。

           二、自旋鎖可能致使死鎖。引起這個問題最多見的狀況是遞歸使用一個自旋鎖,即若是一個已經擁有某個自旋鎖的CPU想第二次得到這個鎖,則CPU將死鎖

           三、自旋鎖鎖按期間不能調用可能引發進程調度的函數。若是進程獲取自旋鎖以後阻塞,如調用copy_from_user()\copy_to_user()\kmalloc()和msleep

                等,則可能致使內核崩潰。

四、信號量:只有獲得信號量的進程才能執行臨界區代碼,與自旋鎖不一樣的是,當獲取不到信號量時,進程不會原地打轉而是進入休眠等待狀態,不能用在中斷上下文中

                若是信號量被初始化爲0,則它能夠用於同步,同步意味着一個執行單元的繼續執行需等待另外一執行單元完成某事。

信號量和自旋鎖的區別:

一、信號量是進程級的,用於多個進程之間對資源的互斥,。鑑於進程上下文的切換開銷較大,只有當進程佔用資源時間較長時,用信號量纔是較好的選擇,

    當所要保護的臨界區訪問時間較短時,用自旋鎖是較好的

二、信號量所保護的臨界區可包含可能引發阻塞的代碼,而自旋鎖要避免,由於阻塞意味着要進行進程的切換,若是進程切換出去後,另外一個進程企圖得到

     本自旋鎖,死鎖將發生

三、信號量存在於進程上下文,所以,若是被保護的共享資源須要在中斷或軟中斷狀況下使用,則在信號量和自旋鎖之間只能選擇自旋鎖。

相關文章
相關標籤/搜索