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

来源: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
  • 在本篇教程中,我們學習瞭如何使用 Taurus.MVC WebMVC 框架創建一個簡單的頁面。 我們創建了一個控制器並編寫了一個用於呈現頁面的方法,然後創建了對應的視圖,並最終成功運行了應用程式。 在下一篇教程中,我們將繼續探索 Taurus.MVC WebMVC 框架的更多功能和用法。 ...
  • 一:背景 1. 講故事 很多.NET開發者在學習高級調試的時候,使用sos的命令輸出會發現這裡也看不懂那裡也看不懂,比如截圖中的這位朋友。 .NET高級調試屬於一個偏冷門的領域,國內可觀測的資料比較少,所以很多東西需要你自己去探究源代碼,然後用各種調試工具去驗證,相關源代碼如下: coreclr: ...
  • 我一直都以為c中除以2的n次方可以使用右移n位代替,然而在實際調試中發現並不都是這樣的。是在計算餘數是發現了異常 被除數:114325068 右移15計算結果:3488 除法取整計算結果:3489 右移操作計算餘數:33772 除法取整計算餘數:1005 顯然:這是不一樣的。 移位操作是一條cpu指 ...
  • 在上一篇文章中,我們介紹了ReentrantLock類的一些基本用法,今天我們重點來介紹一下ReentrantLock其它的常用方法,以便對ReentrantLock類的使用有更深入的理解。 ...
  • Excelize 是 Go 語言編寫的用於操作電子錶格辦公文檔的開源基礎庫,2024年2月26日,社區正式發佈了 2.8.1 版本,該版本包含了多項新增功能、錯誤修複和相容性提升優化。 ...
  • 雲採用框架(Cloud Adoption Framework,簡稱CAF)為企業上雲提供策略和技術的指導原則和最佳實踐,幫助企業上好雲、用好雲、管好雲,併成功實現業務目標。本雲採用框架是基於服務大量企業客戶的經驗總結,將企業雲採用分為四個階段,並詳細探討企業應在每個階段採取的業務和技術策略;同時,還 ...
  • 與TXT文本文件,PDF文件更加專業也更適合傳輸,常用於正式報告、簡歷、合同等場合。項目中如果有使用Java將TXT文本文件轉為PDF文件的需求,可以查看本文中介紹的免費實現方法。 免費Java PDF庫 本文介紹的方法需要用到Free Spire.PDF for Java,該免費庫支持多種操作、轉 ...
  • 指針和引用 當我們需要在程式中傳遞變數的地址時,可以使用指針或引用。它們都可以用來間接訪問變數,但它們之間有一些重要的區別。 指針是一個變數,它存儲另一個變數的地址。通過指針,我們可以訪問存儲在該地址中的變數。指針可以被重新分配,可以指向不同的變數,也可以為NULL。指針使用*運算符來訪問存儲在地址 ...
  • 即使再小再簡單的需求,作為研發開發完畢之後,我們可以直接上線麽?其實很多時候事故往往就是由於“不以為意”發生的。事故的發生往往也遵循“墨菲定律”,這就要求我們更要敬畏線上,再小的需求點都需要經過嚴格的測試驗證才能上線。 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、是什麼 許可權是對特定資源的訪問許可,所謂許可權控制,也就是確保用戶只能訪問到被分配的資源 而前端許可權歸根結底是請求的發起權,請求的發起可能有下麵兩種形式觸發 頁面載入觸發 頁面上的按鈕點擊觸發 總的來說,所有的請求發起都觸發自前端路由或 ...