在rtthread中,互斥量不能在中斷服務例程中使用?以及線程多次持有互斥量的情況怎么理解?

? ? ? ? 互斥鎖的所有權:

????????互斥量的狀態只有兩種,開鎖或閉鎖(兩種狀態值)。當有線程持有它時,互斥量處于閉鎖狀態,由這個線程獲得它的所有權。相反,當這個線程釋放它時,將對互斥量進行開鎖,失去它的所有權。當一個線程持有互斥量時,其他線程將不能夠對它進行開鎖或持有它,持有該互斥量的線程也能夠再次獲得這個鎖而不被掛起,這個特性與一般的二值信號量有很大的不同:在信號量中,線程遞歸持有會發生主動掛起(最終形成死鎖)。

一、為什么互斥量不能在中斷服務例程中使用?

????????首先必須明確一點,無論是在裸機還是RTOS實時操作系統,在中斷服務ISR中,都要求中斷處理快速執行,絕對不允許中斷出現任何阻塞的操作,否則會影響確保其他任務的實時運行,破壞系統的穩定性。

? ? ? ? 對于任何RTOS實時操作系統,在中斷服務ISR中,無論是對于互斥鎖 Mutex 還是 信號量 sem,絕對不允許出現任何可能阻塞中斷處理的行為和操作。

????????即:堅決不能在中斷服務ISR中,調用 take mutex 或者 take sem。因為當其他線程中一旦已經獲取 mutex 或 sem 時,當中斷 INT 打斷線程,進行中斷上下文切換時,在中斷服務ISR中,執行take mutex 或者 take sem操作,將使的整個中斷進入阻塞狀態。嚴重影響破壞整個系統的實時性和穩定性。

1.?根本原因:阻塞特性

互斥量(mutex)的核心特性是可能引發阻塞

  • 當互斥量已被占用時,rt_mutex_take()?會阻塞當前線程

  • 中斷上下文不允許阻塞(必須快速執行并退出),因為 阻塞操作會觸發線程調度rt_schedule(),保存線程切換時的上下文到TCB,但是 中斷上下文沒有線程控制塊TCB可被調度使用。

2.?中斷上下文限制

????????中斷服務例程 ISR 運行在中斷上下文中,在中斷中是沒有所謂的線程上下文的(例如當前線程控制塊),而互斥量的操作依賴于 Thread 線程上下文(eg:記錄持有hold互斥量的當前線程)

同時源碼中明確表示,在中斷中禁用:

3.?優先級繼承的不可行性

互斥量有優先級繼承機制:

  • 中斷沒有"線程任務優先級"的概念,無法參與優先級繼承

  • 中斷沒有線程控制塊 TCBstruct rt_thread),沒有辦法去記錄線程的優先級相關參數

總結: 為什么中斷中不可以釋放互斥鎖(mutex)和 獲取 mutex?

????????互斥鎖具有所有權概念,只有持有鎖的線程才能釋放它。中斷上下文沒有線程控制塊(即沒有線程身份),因此無法滿足互斥鎖的所有權要求。此外,互斥鎖的釋放操作可能涉及優先級繼承的解除,這需要修改持有鎖的線程的優先級,而中斷上下文無法安全地執行這些操作(因為可能涉及調度,而中斷中不能調度)。

二、線程多次持有互斥量的理解

1.?遞歸鎖特性

????????互斥量有一個特性叫做 " 遞歸鎖(Recursive Lock)",即同一個線程可以多次獲取(take)同一個互斥量,而不會造成死鎖。每次獲取互斥量后,必須對應相同次數的釋放(release)操作,互斥量才會真正被釋放給其他線程。

例如如下使用:

rt_mutex_t mutex;
void thread_function(void)
{// 第一次獲取互斥量rt_mutex_take(mutex, RT_WAITING_FOREVER);// ... 執行一些操作 ...// 第二次獲取同一個互斥量(同一個線程)rt_mutex_take(mutex, RT_WAITING_FOREVER); // 這里不會阻塞,因為已經持有該互斥量// ... 更多操作 ...// 第一次釋放互斥量(互斥量仍然被持有,因為獲取了兩次)rt_mutex_release(mutex);// 第二次釋放互斥量,此時互斥量才真正被釋放rt_mutex_release(mutex);
}

Mutex 為什么需要多次獲取?

????????這種情況通常出現在遞歸函數中,或者在一個函數中調用了另一個函數,而這兩個函數都需要操作同一個互斥量保護的數據。例如:

void function_a(void)
{rt_mutex_take(mutex, RT_WAITING_FOREVER);function_b(); // 這個函數內部也會獲取同一個互斥量rt_mutex_release(mutex);
}
void function_b(void)
{rt_mutex_take(mutex, RT_WAITING_FOREVER);// 做一些操作rt_mutex_release(mutex);
}

????????如果沒有遞歸鎖的特性那么當線程在`function_a`中已經持有互斥量,再進入`function_b`嘗試獲取同一個互斥量時,就會發生死鎖(因為線程會等待自己釋放互斥量)。而遞歸鎖允許這種情況發生,因為同一個線程多次獲取同一個互斥量是允許的。

?2. 遞歸深度

????????RT-Thread的互斥量支持有限次數的遞歸獲取(具體次數由`RT_MUTEX_VALUE_MAX`定義,默認是0xFFFF)。超過這個次數會導致獲取失敗。

3. 釋放次數

????????必須確保 互斥鎖mutex 獲取和釋放的次數匹配,否則會導致互斥量無法被其他線程獲取,或者提前釋放導致其他線程錯誤地獲取到互斥量。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96015.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96015.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96015.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣32:最長有效括號

力扣32:最長有效括號題目思路代碼題目 給你一個只包含 ‘(’ 和 ‘)’ 的字符串,找出最長有效(格式正確且連續)括號 子串 的長度。 左右括號匹配,即每個左括號都有對應的右括號將其閉合的字符串是格式正確的,比如 “…

機器學習實例應用

K最近鄰算法K近鄰算法(KNN,k-Nearest Neighbor),每個樣本都可以用它的最接近的K個鄰近值來代表。算法說明:①輸入沒有標簽的新數據,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中特征最相似數據(最近…

力扣 hot100 Day77

連做了幾個動態規劃的中等題,還是比較有套路的,這里只簡要分析一下最長遞增子序列,設定dp[i]為以nums[i]結尾的最長子序列,遞推公式就好推了乘積最大子數組,和上面類似,但考慮到負負得正,所以需…

深入解析RabbitMQ與AMQP-CPP:從原理到實戰應用

一、RabbitMQ安裝 1.安裝 RabbitMQ sudo apt install rabbitmq-serverRabbitMQ 的簡單使用 # 啟動服務 sudo systemctl start rabbitmq-server.service # 查看服務狀態 sudo systemctl status rabbitmq-server.service # 安裝完成的時候默認有個用戶 guest ,但是權限…

(論文速讀)ViDAR:視覺自動駕駛預訓練框架

論文題目:Visual Point Cloud Forecasting enables Scalable Autonomous Driving(視覺點云預測實現可擴展的自動駕駛) 會議:CVPR2024 摘要:與對通用視覺的廣泛研究相比,可擴展視覺自動駕駛的預訓練很少被探…

《Unity Shader入門精要》學習筆記二

1、基礎光照(1)看世界的光模擬真實的光照環境來生成一張圖像,需要考慮3種物理現象。光線從光源中被發射出來。光線和場景中的一些物體相交:一些光線被物體吸收了,而另一些光線被散射到其他方向攝像機吸收了一些光&…

Windchill 11.0使用枚舉類型自定義實用程序實現生命周期狀態管理

一、Enumerated Type Customization Utility 枚舉類型自定義實用程序,可用于添加或編輯枚舉類型的值,在Windchill 12.0+中可直接在類型和屬性管理中編輯,如下圖所示,而在Windchill 11.0中只能通過windchill shell啟動程序,下面將詳細介紹Windchill 11.0中啟動并使用枚舉類…

UGUI源碼剖析(10):總結——基于源碼分析的UGUI設計原則與性能優化策略

UGUI源碼剖析(第十章):總結——基于源碼分析的UGUI設計原則與性能優化策略 本系列文章對UGUI的核心組件與系統進行了深入的源代碼級分析。本章旨在對前述內容進行系統性總結,提煉出UGUI框架最核心的設計原則,并基于這些…

STM32N6引入NPU,為邊緣AI插上“隱形的翅膀”

2025年的春天格外特別。伴隨著人形機器人、DeepSeek的強勢刷屏,AI成了最有前景的賽道。萬物皆可AI,萬物也在尋覓用上AI或者讓AI“轉正”的“aha moment”。 幫助機器更好地“思考”,讓更多的AI走向邊緣,是AI發展的重要趨勢之一。…

演練:使用VB開發多智能體協作的榮格八維分析器

在大語言模型高速發展的時代,我們面對困難的語義分析任務,通過構建智能體進行處理是一個流行趨勢。本文將介紹如何使用 Visual Basic .NET 開發一個多智能體協作系統,用于分析聊天記錄中特定人物的榮格八維人格類型。 本文使用 CC-BY-NC-SA …

llamafactory使用qlora訓練

llamafactory使用qlora訓練 1.環境搭建 conda create -n qlora python3.10 -y conda activate qlora# 克隆LLaMA-Factory倉庫 git clone https://github.com/hiyouga/LLaMA-Factory.git# 進入倉庫目錄 cd LLaMA-Factory# 切換到0.9.4版本 git checkout v0.9.4pip install -e .2…

模型微調/量化技術整理

一、模型微調技術1.模型微調簡介大模型微調(Fine-tuning),是指在已經預訓練好的大語言模型基礎上(基座模型),使用特定的數據集進行進一步訓練,讓模型適應特定任務或領域。通常LLM的預訓練是無監督的,但微調…

實踐筆記-VSCode與IDE同步問題解決指南;程序總是進入中斷服務程序。

一、VSCode 修改文件后,IDE 未同步如果你在 VSCode 中異步修改了項目文件內容,但 S32DS 或 Keil(等集成開發環境)中的項目沒有同步更新,有兩個解決方法:檢查文件是否已保存:確保 VSCode 中修改的…

C#WPF實戰出真汁04--登錄功能實現

1、登錄功能實現要點對于登錄系統,應該注意幾個要點:用戶認證流程設計,密碼存儲與驗證,會話管理,防暴力破解措施,錯誤處理與提示2、登錄功能的視圖模型首先在xaml文件中必須指定該頁面使用的視圖模型&#…

鴻蒙入門簡化版

第一步: 首先下載DEVStudio https://developer.huawei.com/consumer/cn/deveco-studio/ 第二步: 了解基本的ArkTs語言 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/introduction-to-arkts 第三步 : 教學視頻有兩個途徑&a…

day25|學習前端js

函數聲明,被提升(hoisting)。函數表達式必須先定義才能用。對象解構,按屬性名數組解構按順序點運算符. 對象.屬性名哪些可迭代(可以被for..of循環的東西):array,string,m…

quic協議與應用開發

quic為什么出現?quic主要是為了解決TCP協議的局限性而提出的,具體來說是要解決如下問題:1. 加密連接建立時間長TCP協議是傳輸層協議,而TLS是會話層協議,在Linux等主流操作系統中TCP在內核實現而TLS一般在用戶態實現&am…

【淺學】tflite-micro + ESP32S3 + VScode + ESP-IDF 基于例程快速實現自己的圖像分類模型訓練部署全流程

如果你用Pytorch訓練的模型那么可以參考我的步驟,使用的是Tensorflow的話參考官方文檔即可,但流程都是一樣的,每一步我都會提到部分操作細節及注意事項 官方教程 要詳細學習的話tflite-micro里的微控制器章節下都詳細看(頁面左側…

【HarmonyOS】應用設置全屏和安全區域詳解

【HarmonyOS】應用設置全屏和安全區域詳解 一、前言 IDE創建的鴻蒙應用,默認采取組件安全區布局方案。頂部會預留狀態欄區域,底部會預留導航條區域。這就是所謂的安全區域。 如果不處理,界面效果很割裂。所以業內UI交互設計,都會設…

openfeign 只有接口如何創建bean的

OpenFeign 能夠為純接口創建 Spring Bean,其核心機制是通過動態代理和 Spring 的 FactoryBean 機制實現的。以下是詳細的工作原理:1. EnableFeignClients 注解的啟動在 Spring Boot 主類上添加 EnableFeignClients 注解:SpringBootApplicatio…