小米vela系統(基于開源nuttx內核)——如何使用信號量進行PV操作

如何使用信號量進行PV操作

  • 前言
  • 信號量
    • 1. 信號量簡介
    • 2. NuttX中信號量的創建與使用
      • 2.1 Nuttx信號量的初始化和銷毀
      • 2.2 信號量的等待和發布
    • 3. 信號量的實際應用:下載任務示例
      • 3.1 實際代碼
      • 3.2 代碼說明
      • 3.3 執行說明
    • 4. 信號量的優勢與應用場景
    • 5. 常見應用場景:
  • 總結

前言

在嵌入式系統中,任務間的同步與通信是非常重要的。NuttX作為一款輕量級實時操作系統,提供了多種同步機制,其中信號量(Semaphore)是一種常見且高效的工具,用于實現線程或任務之間的同步。本文將深入探討如何在NuttX中使用信號量,并通過一個實例來展示其應用。

在 Vela 操作系統(nuttx內核)中,使用標準的 POSIX接口,信號量的管理也是與linux系統類似的。
在這里插入圖片描述

信號量

1. 信號量簡介

信號量是一種用于線程間同步的機制,它可以控制多個任務的訪問權限。常見的信號量類型有:

二值信號量(Binary Semaphore):信號量的值只有兩個狀態,0和1,常用于實現互斥鎖。
計數信號量(Counting Semaphore):信號量的值可以為任意正整數,適用于控制某些資源的訪問數量。
信號量通常由一個線程/任務進行“發布”(sem_post()),另一個線程/任務進行“等待”(sem_wait())。通過這種機制,任務可以在特定條件下進行同步,確保共享資源的安全訪問。

在NuttX系統中,信號量的實現和使用與POSIX標準兼容,開發者可以使用標準的API來進行操作。

2. NuttX中信號量的創建與使用

NuttX提供了一些API來操作信號量,常見的函數包括:

  • sem_init():初始化信號量。
  • sem_wait():等待信號量,如果信號量值為0,則阻塞當前線程,直到信號量被發布。
  • sem_post():發布信號量,增加信號量的值,可能會解除一個等待信號量的線程阻塞。
  • sem_destroy():銷毀信號量。

這些API非常方便地用于線程同步,特別是在多線程環境下。

2.1 Nuttx信號量的初始化和銷毀

這里申明了一個全局的下載標志信號量,初始化為0,表示當調用wait信號量的線程在程序開始時候就會被阻塞住回等待信號量來觸發執行

sem_t g_download_sem;  // 聲明信號量// 初始化信號量
sem_init(&g_download_sem, 0, 0);  // 初始值為0,表示線程會等待// 銷毀信號量
sem_destroy(&g_download_sem);
  • sem_init(&g_download_sem, 0, 0):初始化一個信號量 g_download_sem,第二個參數為0表示信號量在進程間共享,第三個參數為0表示信號量的初始值為0。
  • sem_destroy(&g_download_sem):銷毀信號量,釋放資源。

2.2 信號量的等待和發布

// 等待信號量
sem_wait(&g_download_sem);// 發布信號量
sem_post(&g_download_sem);
  • sem_wait(&g_download_sem):如果信號量的值為0,調用該函數的線程會被阻塞,直到信號量被發布(sem_post())。
  • sem_post(&g_download_sem):發布信號量,將信號量的值加1。如果有線程在等待該信號量,它將被喚醒,繼續執行。

3. 信號量的實際應用:下載任務示例

為了更好地理解信號量的使用,接下來通過一個示例來演示信號量如何用于任務間同步。該示例涉及兩個線程,一個是常駐線程(download_thread),等待信號量來觸發下載任務,另一個線程(signal_thread)負責發送信號量,觸發下載。

3.1 實際代碼

#include <nuttx/config.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>sem_t g_download_sem;  // 全局信號量// 下載任務函數
void download_task(void)
{printf("Downloading... \n");usleep(2000000);  // 模擬下載過程printf("Download completed!\n");
}// 常駐下載線程,等待信號量并執行下載任務
void *download_thread(void *arg)
{while (1){printf("Download thread waiting for signal...\n");// 等待信號量sem_wait(&g_download_sem);// 收到信號量后執行下載任務download_task();}return NULL;
}// 發送信號量的線程
void *signal_thread(void *arg)
{// 模擬在某個時間點或條件觸發信號量sleep(1);  // 模擬等待1秒printf("Signal thread sending signal to download thread...\n");// 給信號量發送信號,觸發下載任務sem_post(&g_download_sem);return NULL;
}int main(int argc, char *argv[])
{pthread_t download_tid, signal_tid;// 初始化信號量sem_init(&g_download_sem, 0, 0);  // 初始信號量為0,線程開始時會等待// 創建下載線程pthread_create(&download_tid, NULL, download_thread, NULL);// 創建發送信號量的線程pthread_create(&signal_tid, NULL, signal_thread, NULL);// 等待信號線程完成pthread_join(signal_tid, NULL);// 等待下載線程執行完畢pthread_join(download_tid, NULL);// 清理信號量sem_destroy(&g_download_sem);return 0;
}

3.2 代碼說明

  • 常駐下載線程(download_thread
    • 該線程持續運行,并在每次調用 sem_wait(&g_download_sem) 時阻塞,直到接收到信號量。信號量的接收標志著可以開始下載任務。
  • 信號量觸發線程(signal_thread
    • 在模擬的條件下(例如延時1秒),該線程會調用 sem_post(&g_download_sem) 來觸發下載線程開始執行下載任務。
  • 主線程(main
    • 主線程初始化信號量,創建并啟動下載線程和信號量觸發線程,最后等待它們的執行完成并清理資源。

3.3 執行說明

  • 程序啟動后,main 線程創建兩個線程:

    • download_thread 會等待信號量,并在收到信號量后執行下載任務。
    • signal_thread 在延時1秒后觸發信號量,使得 download_thread 執行下載任務。
  • signal_thread 發送信號量后,download_thread 被喚醒并開始執行模擬的下載任務。

  • 最后,main 線程等待兩個子線程執行完畢,并清理信號量資源。

4. 信號量的優勢與應用場景

信號量作為一種同步機制,在多線程或多任務的系統中有廣泛的應用。它的優勢在于:

  • 簡單性:信號量的基本操作非常簡單,可以輕松實現任務間的同步。
  • 高效性:信號量的實現通常很輕量,適用于需要低延遲和高效同步的場景。
  • 靈活性:可以通過計數信號量控制資源的訪問數量,通過二值信號量實現互斥。

5. 常見應用場景:

  1. 任務同步:當多個任務之間需要協調工作時,可以使用信號量來同步它們的執行。
  2. 資源管理:在有限資源的情況下,信號量可以用來限制并發任務的數量。例如,限制同時訪問某個硬件資源的線程數。
  3. 事件通知:一個任務等待某個事件的發生,另一個任務在事件發生時發布信號量來通知等待任務。

總結

NuttX提供了POSIX兼容的信號量API,使得在多線程環境下進行任務同步變得更加簡單和高效。通過本文中的示例,我們了解了如何在NuttX中創建和使用信號量,并展示了如何利用信號量控制任務的執行。信號量在嵌入式系統中應用廣泛,特別是在需要多任務協作和資源管理的場景中,信號量提供了一種簡潔的解決方案。

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

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

相關文章

CMake學習筆記(2)

1. 嵌套的CMake 如果項目很大&#xff0c;或者項目中有很多的源碼目錄&#xff0c;在通過CMake管理項目的時候如果只使用一個CMakeLists.txt&#xff0c;那么這個文件相對會比較復雜&#xff0c;有一種化繁為簡的方式就是給每個源碼目錄都添加一個CMakeLists.txt文件&#xff…

旅游網站設計與實現

文末附有完整項目代碼 在當今數字化時代&#xff0c;旅游網站成為人們獲取旅游信息的重要途徑。本文將詳細介紹旅游網站的設計與實現&#xff0c;讓你輕松了解其中的技術奧秘&#xff01; 一、項目背景 隨著社會經濟的發展&#xff0c;人們對精神消費愈發重視&#xff0c;旅游…

【C++】size_t究竟是什么?全面解析與深入拓展

博客主頁&#xff1a; [小????????] 本文專欄: C 文章目錄 &#x1f4af;前言&#x1f4af;一、什么是size_t&#xff1f;為什么需要size_t&#xff1f; &#x1f4af;二、size_t的特性與用途1. size_t是無符號類型示例&#xff1a; 2. size_t的跨平臺適應性示例對…

【物流管理系統 - IDEAJavaSwingMySQL】基于Java實現的物流管理系統導入IDEA教程

有問題請留言或私信 步驟 下載項目源碼&#xff1a;項目源碼 解壓項目源碼到本地 打開IDEA 左上角&#xff1a;文件 → 新建 → 來自現有源代碼的項目 找到解壓在本地的項目源代碼文件&#xff0c;點擊確定&#xff0c;根據圖示步驟繼續導入項目 查看項目目錄&#xff…

ssh2-sftp-client和ssh2配合使用js腳本快速部署項目到服務器

有時候因為服務器不能實現github或者gitlab的自動部署服務&#xff0c;所以就需要使用腳本來實現自動部署&#xff0c;可以省時省力&#xff0c;一勞永逸。這里就使用ssh2-sftp-client和ssh2來實現&#xff0c;即便是需要sudo權限&#xff0c;也是可以的。 1.先將本地打包后的…

深度解析Linux中的調試器gdb/cgdb的使用

Linux下我們編譯好的代碼&#xff0c;無法直接調試 gcc/g默認的工作模式是realse模式 程序要調試的話&#xff0c;必須是debug模式&#xff0c;也就是說編譯的時候要加-g選項 gdb攜帶調試信息的exe 我們現在在文件夾里面創建一個文件lesson11 里面創建一個累加的代碼&…

【Maui】動態菜單實現(綁定數據視圖)

前言 .NET 多平臺應用 UI (.NET MAUI) 是一個跨平臺框架&#xff0c;用于使用 C# 和 XAML 創建本機移動和桌面應用。 使用 .NET MAUI&#xff0c;可從單個共享代碼庫開發可在 Android、iOS、macOS 和 Windows 上運行的應用。 .NET MAUI 是一款開放源代碼應用&#xff0c;是 X…

Bash語言的語法糖

Bash語言的語法糖 引言 在現代編程語言中&#xff0c;“語法糖”是一個非常常見的術語&#xff0c;它指的是那些使代碼更加易讀、易寫的語法特性。盡管這些特性并不改變語言的功能&#xff0c;但它們能顯著提升開發者的編程體驗。在眾多編程語言中&#xff0c;Bash&#xff0…

linux---Nginx詳細教程(包含安裝,網站部署)

Nginx是一個高性能的HTTP和反向代理服務器&#xff0c;也可以用作郵件代理服務器&#xff0c;其以占有內存少、并發能力強、穩定性高、豐富的功能集、低系統資源消耗而聞名。以下是對Nginx的詳細教程&#xff1a; 一、Nginx簡介 Nginx由俄羅斯人開發&#xff0c;第一個公開版…

RNN之:LSTM 長短期記憶模型-結構-理論詳解-及實戰(Matlab向)

0.前言 遞歸&#xff01;循環神經網絡Recurrent Neural Network 循環神經網絡&#xff08;又稱遞歸神經網絡&#xff0c;Recurrent Neural Network&#xff0c;RNN&#xff09;。是一種用于處理序列數據的神經網絡結構&#xff0c;具有記憶功能&#xff0c;能夠捕捉序列中的時…

泛目錄和泛站有什么差別

啥是 SEO 泛目錄&#xff1f; 咱先來說說 SEO 泛目錄是啥。想象一下&#xff0c;你有一個巨大的圖書館&#xff0c;里面的書架上擺滿了各種各樣的書&#xff0c;每一本書都代表著一個網頁。而 SEO 泛目錄呢&#xff0c;就像是一個超級圖書管理員&#xff0c;它的任務就是把這些…

初識@ffmpeg/ffmpeg庫

前言 FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并且能夠利用它們來創建一個新的流媒體格式的自由軟件項目,它被廣泛應用在視頻處理、音頻處理以及直播領域。其中,@ffmpeg/ffmpeg 是一個將 FFmpeg 編譯為 WebAssembly(WASM)的庫,可支持幾乎所有的音視頻格式。 安裝…

【圖像去噪】論文復現:反向擴散中加入MAP將擴散模型從高斯去噪推廣到真實去噪!DiffusionVI的Pytorch源碼復現,跑通源碼,梳理理論,單卡可執行!

請先看【專欄介紹文章】:【圖像去噪(Image Denoising)】關于【圖像去噪】專欄的相關說明,包含適配人群、專欄簡介、專欄亮點、閱讀方法、定價理由、品質承諾、關于更新、去噪概述、文章目錄、資料匯總、問題匯總(更新中) 完整代碼和訓練好的模型權重文件下載鏈接見本文底…

Windows 藍牙驅動開發-簡介

藍牙(英語&#xff1a;Bluetooth)是一種無線通信技術標準&#xff0c;用來讓固定與移動設備&#xff0c;在短距離間交換資料&#xff0c;以形成個人局域網(PAN)。其使用短波特高頻(UHF)無線電波&#xff0c;經由2.4至2.485 GHz的ISM頻段來進行通信。1994年由電信商愛立信(Erics…

【Vue】全局/局部組件使用流程(Vue2為例)

全局組件和局部組件區別 如何使用 全局組件&#xff1a;全局注冊后&#xff0c;可以在任意頁面中直接使用。局部組件&#xff1a;在頁面中需要先導入子組件路徑&#xff0c;注冊組件才能使用。 適用場景 全局組件&#xff1a;適用于高頻使用的組件&#xff0c;如導航欄、業…

【Pytorch實用教程】PyTorch 中如何輸出模型參數:全面指南

文章目錄 PyTorch 中如何輸出模型參數:全面指南1. 為什么需要輸出模型參數?2. PyTorch 中輸出模型參數的方法2.1 使用 `model.parameters()` 輸出所有參數2.2 使用 `model.named_parameters()` 輸出參數名稱和值2.3 使用 `model.state_dict()` 輸出模型的參數字典2.4 輸出特定…

vscode vue 自動格式化

vscode vue 自動格式化 安裝Prettier和Vetur插件 選擇設置&#xff0c;并且轉到編輯文件。增加如下內容。 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","[vue]": {"editor.defaultFor…

1、docker概念和基本使用命令

docker概念 微服務&#xff1a;不再是以完整的物理機為基礎的服務軟件&#xff0c;而是借助于宿主機的性能。以小量的形式&#xff0c;單獨部署的應用。 docker&#xff1a;是一個開源的應用容器引擎&#xff0c;基于go語言開發的&#xff0c;使用時apache2.0的協議。docker是…

Genymotion配套VirtualBox所在地址

在 Genymotion打開虛擬機前需要先打開VirtualBox中的虛擬機 C:\Program Files\Oracle\VirtualBox\VirtualBox.exe 再開啟genymotion中的虛擬機開關

【Linux】深刻理解軟硬鏈接

一.軟硬鏈接操作 1.軟連接 touch 創建一個文件file.txt &#xff0c;對該文件創建對應的軟鏈接改怎么做呢&#xff1f; ln -s file.txt file-soft.link .給對應文件創建軟連接。 軟連接本質就是一個獨立的文件&#xff0c;因為我們對應的軟連接有獨立的inode&#xff0c;他…