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

来源: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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...