驅動開發學習筆記---併發與競爭

来源:https://www.cnblogs.com/zhuzi1/archive/2022/11/27/16930729.html
-Advertisement-
Play Games

一、併發與競爭簡介 併發:多個“用戶”同時訪問一個共用的記憶體。 競爭:多個“用戶”同時訪問一段共用的記憶體並對其修改,就會造成數據混亂,甚至程式崩潰,這就是競爭。 二、造成併發與競爭的原因 1、多線程併發訪問, Linux 是多任務(線程)的系統,所以多線程訪問是最基本的原因。 2、搶占式併發訪問, ...


一、併發與競爭簡介

併發:多個“用戶”同時訪問一個共用的記憶體。

競爭:多個“用戶”同時訪問一段共用的記憶體並對其修改,就會造成數據混亂,甚至程式崩潰,這就是競爭。

二、造成併發與競爭的原因

1、多線程併發訪問, Linux 是多任務(線程)的系統,所以多線程訪問是最基本的原因。

2、搶占式併發訪問, Linux 內核支持搶占,也就是說調度程式可以在任意時刻搶占正在運行的線程,從而運行其他的線程。

3、中斷程式併發訪問,這個無需多說,學過 STM32 的同學應該知道,硬體中斷的權利可是很大的。

4、 SMP(多核)核間併發訪問,現在 ARM 架構的多核 SOC 很常見,多核 CPU 存在核間併發訪問。

三、臨界區(共用資源

在多任務的工作模式下有多個執行單位,它們通常可以擁有一段共用空間(比如全局變數、共用記憶體等等)。所以要對共用資源進行保護,某個線程局部變數不需要保護,要保護的是多個線程都會訪問的共用數據。如:全局變數,設備結構體成員

四、避免併發與競爭的操作:

1、原子操作

原子操作就是指不能再進一步分割的操作,一般原子操作用於變數或者位操作。

對於基本的賦值操作比如a=1;在內核裡面的步驟為:

ldr r0, =0X30000000         // 變數 a 地址 
ldr r1, = 3                 // 要寫入的值 
str r1, [r0]                // 將 3 寫入到 a 變數中 

因為一個簡單的賦值就有三條語句,然後在多進程裡面就可以能出現競爭現象

image-20221127205312878

在編寫驅動時,對全局變數要求保證原子操作可以用 atomic_t 結構體:

typedef struct {
int counter;
} atomic_t;

通過原子整形API庫函數進行整形操作和位操作。

2、自旋鎖

原子操作可以用來解決變數訪問的問題,我們在實際應用中有時候需要操作的不止是變數,還有一塊區域(比如結構體變數)等。為了保護他們,我們就添加了各種鎖,比如自旋鎖。自旋鎖適用於短時期輕量級加鎖,長時間就用信號量。

自旋鎖使用註意事項:

  1. 因為等待資源的線程會一直“自旋”,所以線程持有自旋鎖,訪問臨界區的時間不能太長。

  2. 臨界區中,不能存在任何會引起線程阻塞、睡眠的操作,否者可能引起死鎖。

  3. 不能遞歸的申請自旋鎖。

  4. 考慮到程式的可移植性,在使用自旋鎖時不管你的cpu是單核,還是多核,都當做多核來使用。

死鎖:線程在獲取鎖之後阻塞或睡眠,導致多個線程都阻塞。

自旋鎖會自動禁止搶占,也就說當線程 A得到鎖以後會暫時禁止內核搶占。如果線程 A 在持有鎖期間進入了休眠狀態,那麼線程 A 會自動放棄 CPU 使用權。線程 B 開始運行,線程 B 也想要獲取鎖,但是此時鎖被 A 線程持有,而且內核搶占還被禁止了!線程 B 無法被調度出去,那麼線程 A 就無法運行,鎖也就無法釋放,好了,死鎖發生了!

3.信號量

在這裡插入圖片描述

信號量特點:

1.線程可以訪問的臨界區比較大,訪問資源的時間長,所以臨界區中可以調用引起阻塞的操作。 2.等待資源的線程不會一直等待,會讓出 cpu 使用權,進入掛起、睡眠狀態。(cpu經過調度執行其它線程) 3.正是因為會進入睡眠態,所以不能在中斷中使用,同時也不能在自旋鎖的臨界區中使用。(中斷講究快進快出) 4.在等待資源時CPU 會經歷 切換、喚醒進程等等操作,會產生一定的開銷。當使用信號量所爭取的利益大於這個開銷時就不要使用信號量。

4.互斥體

信號量值 = 1 可以實現互斥訪問,Linux 比信號量更專業的機制來進行互斥,即互斥體 mutex。使用過程中有其它線程想要獲取該資源的鎖,那麼它就會被阻塞陷入睡眠狀態,直到該資源被解鎖才會被喚醒。

互斥體特點: 1.mutex 可以導致休眠,因此也不能在中斷中使用 mutex,中斷中只能使用自旋鎖。 2.和信號量一樣, mutex 保護的臨界區可以調用引起阻塞的 API 函數。(臨界區中可以引起塞) 3.因為一次只有一個線程可以持有 mutex,因此,必須由 mutex 的持有者釋放 mutex。並且 mutex 不能遞歸上鎖和解鎖。

互斥體使用註意事項: 互斥體和自旋鎖都是解決互斥問題的一種手段。互斥體是進程級別的,互斥體在使用的時候會發生進程間的切換,因此,使用互斥體資源開銷比較大。自旋鎖可以節省上下文切換的時間,如果持有鎖的時間不長,使用自旋鎖是比較好的選擇,如果持有鎖時間比較長,互斥體顯然是更好的選擇。

互斥體與自旋鎖區別: 1.當鎖不能被獲取到時,使用互斥體的開銷是進程上下文切換時間,使用自旋鎖的開銷是等待獲取自旋鎖(由臨界區執行時間決定)。若臨界區比較小,宜使用自旋鎖,若臨界區很大,應使用互斥 體。 2.互斥體所保護的臨界區可包含可能引起阻塞的代碼,而自旋鎖則絕對要避免用來保護包含這樣代碼的臨界區。因為阻塞意味著要進行進程的切換,如果進程被切換岀去後,另一個進程企圖獲取本自旋鎖,死鎖就會發生。 3.互斥體存在於進程上下文。因此,如果被保護的共用資源需要在中斷或軟中斷情況下使用,則在互斥體和自旋鎖之間只能選擇自旋鎖。當然,如果一定要使用互斥體,則只能通過mutextrylock()方式進行,不能獲取就立即返回以避免阻塞。

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 本篇是c++總結的第二篇,關於c++的對象模型,在構造、拷貝虛函數上重點分析,也包含了c++11class的新用法和特性,如有不當,還請指教! c++三大特性 訪問許可權 ​ 在c++中通過public、protected、private三個關鍵字來控製成員變數和成員函數的訪問許可權,它們分別表示 ...
  • Spring 框架可以為 Java 應用程式開發提供全面的基礎設施支持,它是現在非常流行的 Java 開源框架,對於一個 Java 開發人員來說,熟練掌握 Spring 是必不可少的。 ...
  • 1. 查看Linux伺服器版本信息 # cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 2. 禪道開源版安裝包下載 wget http://dl.cnezsoft.com/zentao/9.8.2/ZenTaoPMS.9.8. ...
  • 目錄 一.OpenGL 色階 1.Windows OpenGL ES 版本 2.Windows OpenGL 版本 二.OpenGL 色階 GLSL Shader 三.猜你喜歡 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎 零基礎 Ope ...
  • 我們都知道在Java編程中多線程的同步使用synchronized關鍵字來標識,那麼這個關鍵字在JVM底層到底是如何實現的呢。 我們先來思考一下如果我們自己實現的一個鎖該怎麼做呢: 首先肯定要有個標記記錄對象是否已經上鎖,執行同步代碼之前判斷這個標誌,如果對象已經上鎖線程就阻塞等待鎖的釋放。 其次要 ...
  • JZ7重建二叉樹 描述 給定節點數為 n 的二叉樹的前序遍歷和中序遍歷結果,請重建出該二叉樹並返回它的頭結點。 例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6} 提示: 1.vin.length == pre.length 2.pre 和 vin ...
  • 本文是對Datawhale的動手學數據分析課程的學習總結,記錄了整體的學習過程、答案以及個人感想,代碼較為詳細。 ...
  • 簡介 本文的初衷是希望幫助那些有其它平臺視覺演算法開發經驗的人能快速轉入Halcon平臺下,通過文中的示例開發者能快速瞭解一個Halcon項目開發的基本步驟,讓開發者能把精力完全集中到演算法的開發上面。 首先,你需要安裝Halcon,HALCON 18.11.0.1的安裝包會放在文章末尾。安裝包分開發和 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...