色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

rt-thread 優化系列(四)信號對 ipc 的影響

出出 ? 來源:出出 ? 作者:出出 ? 2022-06-23 09:51 ? 次閱讀

前言

信號 signal,并不是線程間同步的信號量 semaphore。后者是線程間同步機制的一種,而前者是線程間異步通信的一種。
官方文檔里對其解釋是:“信號(又稱為軟中斷信號),在軟件層次上是對中斷機制的一種模擬,在原理上,一個線程收到一個信號與處理器收到一個中斷請求可以說是類似的。”

信號本質是**軟中斷**,用來通知線程發生了異步事件,**用做線程之間的異常通知、應急處理**。一個**線程不必通過任何操作來等待信號的到達**,事實上,**線程也不知道信號到底什么時候到達**。線程之間可以互相通過調用 `rt_thread_kill` 發送信號。

以上畫線部分是我特意要大家注意的,我們要看待中斷回調函數那樣,看待信號回調函數**被執行的實機**,但不需要過分擔憂的是回調函數**執行時間**,因為**終究信號回調函數還是在線程上下文被執行的**。

從官方文檔可以清楚了解到,使用信號很簡單,安裝信號、解除信號掩碼、發送信號、處理信號等幾個過程。

更多關于信號的原理詳見官方文檔 [信號]( https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/ipc2/ipc2?id=%e4%bf%a1%e5%8f%b7 )

一個示例引起的血案

官方原版示例筆者就不貼出來了,直接拷貝到自己的項目完美運行。但是,筆者經過如下修改,發現一點兒疑問。

/* 線程 1 的入口函數 */
static void thread1_entry(void *parameter)
{
...
while (cnt < 10)
   {
       ...
       tick = rt_tick_get();
       rt_thread_mdelay(1000);
       tick = rt_tick_get();
   }
   ...
}

把延時時間增長,前后添加測時。多次運行發現 tick 值改變只有 300 (`rt_thread_mdelay(300)`)。這說明了線程響應 signal 后,處理了信號回調函數之后放棄了之前的延時!那么問題來了,應用層想要的延時時間不足,應用層知道嗎?答案是,*不知道!*

rt-thread 中阻塞函數列表

前一段時間在文章 rt-thread 那些你必須知道的幾類 api 里總結了 *禁止在中斷中調用*、*必須在任務調度器運行以后才能使用*、*不能用在線程自己身上*的幾類 api。

可能還缺一種:哪些 api 會引起線程調度,使得當前線程放棄 cpu 使用權——所有調用 `rt_schedule` 的函數都屬于這類。這里邊又分三種情況,一種是時間片耗盡讓出 cpu 使用權;一種是釋放資源或者信號讓出 cpu 使用權;還有一種是等待資源而被動放棄 cpu。最后這種情況,是有目地的,往往希望有資源可用了之后從阻塞中恢復繼續運行,如果線程從阻塞中恢復運行但同時沒有資源可用是不是就烏龍了?以下的關注重點也是這類函數。

所有第三類引起線程調度的函數和上面的 `rt_thread_mdelay` 一樣,在 signal 面前可能遇到一樣的遭遇。大體上,分這么幾類:

  • 延時函數
  • 線程間同步機制函數
  • 線程間通信機制部分函數(signal除外)
  • posix 下的 select poll 等接口(可能使用了線程間同步和通信機制)

這幾類在遇到 signal 之后行為分別是什么樣的?

被阻塞函數遇到 signal 后什么反應?

延時函數遇到 signal

這個前面已經經過測試的了,它會退出阻塞提前結束延時,但是應用層并不知道是達到延時時間還是有信號。

線程間同步通信機制函數遇到 signal

  • `rt_sem_take` 線程 error 非 RT_EOK (包括 RT_EINTR)直接返回線程錯誤狀態
   /* do schedule */
   rt_schedule();
   if (thread->error != RT_EOK)
   {
       return thread->error;
   }
  • `rt_mutex_take` 考慮到了 signal 的影響,返回繼續阻塞等待 `time` 時間。這是 ipc 里唯一例外的一個。
               /* do schedule */
               rt_schedule();

               if (thread->error != RT_EOK)
               {
#ifdef RT_USING_SIGNALS
                   /* interrupt by signal, try it again */
                   if (thread->error == -RT_EINTR) goto __again;
#endif /* RT_USING_SIGNALS */

其它,其余的 ipc 都和 `rt_sem_take` 一樣。

完成量遇到 signal

`rt_completion_wait` 返回線程錯誤狀態。

           /* do schedule */
           rt_schedule();
           /* thread is waked up */
           result = thread->error;

           level = rt_hw_interrupt_disable();
       }
   }
   ...

   return result;

select poll 等接口與 signal

因為文件描述符對應的設備不盡相同,設備底層實現 `poll` 的方式可能也千差萬別,但是他們大概率是使用上面的線程間同步和通信機制了。

`poll` 實現過程調用個超時等待函數 `poll_wait_timeout` ,它也沒有區分超時和信號兩種情況。

       rt_schedule();
       level = rt_hw_interrupt_disable();
   }

   ret = !pt->triggered;
   rt_hw_interrupt_enable(level);

   return ret;

我們發現,`rt_sem_take` 結束了阻塞,并可能返回了 `RT_EINTR` ,而 `rt_mutex_take` 繼續了循環阻塞。

等待資源而被動放棄 cpu 時怎么應對 signal 才合適?

現做以下約定,等待資源而被動放棄 cpu 的線程在此約定下,當有 signal 的時候會提前結束阻塞,返回應用層,應用層可以根據線程錯誤狀態區別處理。

1. 復位線程錯誤狀態為 `RT_EOK` 。
2. 調用 `rt_schedule` 進行線程調度,線程被阻塞掛起。
3. 從 `rt_schedule` 恢復喚醒,有一定手段通知到應用層(返回線程錯誤狀態),應用層可以區分出是因為資源可用還是因為信號。

哪些 api 做到了以上這幾點呢?

```
rt_completion_wait
rt_sem_take
rt_event_recv
rt_mb_send_wait
rt_mb_recv
rt_mq_send_wait
rt_mq_recv
rt_data_queue_push
rt_data_queue_pop

rt_mp_alloc

哪些 api 沒有做到以上幾點?

```
rt_mutex_take
rt_thread_sleep
rt_thread_delay
rt_thread_delay_until
rt_thread_mdelay
rt_wqueue_wait

筆者曾經在 gitee 上提交過一個 [issue]( https://gitee.com/rtthread/rt-thread/issues/I44JNS ) ,當時筆者隱隱中認為 ipc 中的不一致行為總有些隱患,感覺所有的阻塞等待都應該處理一下意外喚醒后的超時等待。卻沒意識到有什么意外情況可以讓這些函數從阻塞等待中提前退出。通過研究 signal 實現原理的過程中發現,這種意外情況還有存在的,只是擔憂的問題重點變了,不是處理阻塞等待剩余時間,而是在 signal 的影響下通知應用層的問題。

解決方案

有了上面的梳理,下面的修改方向就有了,改動范圍也確定了。

  • 幾個延時函數返回 `thread->error` 代替目前的 `RT_EOK` ;
  • `rt_mutex_take` 去掉 `goto __again` 也返回 `thread->error` ;
  • `rt_wqueue_wait` 返回 `thread->error` 代替目前的 `RT_EOK` 。
  • `poll` 目前返回值是 >= 0 的,返回 0 可能是超時,也可能是被信號中斷了。暫時不發表修改意見。

結束語

以上搜索不一定完整完全,但應該包括了大部分受到影響的函數。如果看客有發現其它的 api 有不符合上述約定行為的,請留言告知,謝謝!

本人能力有限,文中難免有錯誤。望各位同仁不吝賜教。

相關文章

rt-thread 優化系列(0) SysTick 優化分析

rt-thread 優化系列(一) 之 過多關中斷

rt-thread 優化系列(二) 之 同步和消息關中斷分析

rt-thread優化系列(三)軟定時器的定時漂移問題分析


審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 信號
    +關注

    關注

    11

    文章

    2790

    瀏覽量

    76741
  • IPC
    IPC
    +關注

    關注

    3

    文章

    347

    瀏覽量

    51905
  • signal
    +關注

    關注

    0

    文章

    110

    瀏覽量

    24916
  • RT-Thread
    +關注

    關注

    31

    文章

    1286

    瀏覽量

    40102
收藏 人收藏

    評論

    相關推薦

    RT-Thread記錄(二、RT-Thread內核啟動流程)

    在前面我們RT-Thread Studio工程基礎之上講一講RT-Thread內核啟動流程.
    的頭像 發表于 06-20 00:30 ?5031次閱讀
    <b class='flag-5'>RT-Thread</b>記錄(二、<b class='flag-5'>RT-Thread</b>內核啟動流程)

    【原創精選】RT-Thread征文精選技術文章合集

    漂移問題分析rt-thread 優化系列信號ipc 的影響
    發表于 07-26 14:56

    RT-Thread編程指南

    RT-Thread編程指南——RT-Thread開發組(2015-03-31)。RT-Thread做為國內有較大影響力的開源實時操作系統,本文是RT-Thread實時操作系統的編程指南
    發表于 11-26 16:06 ?0次下載

    RT-Thread用戶手冊

    RT-Thread用戶手冊——本書是RT-Thread的編程手冊,用于指導在RT-Thread實時操作系統環境下如何進行編 程。
    發表于 11-26 16:16 ?0次下載

    RT-Thread Studio驅動SD卡

    RT-Thread Studio驅動SD卡前言一、創建基本工程1、創建Bootloader2、創建項目工程二、配置RT-Thread Settings三、代碼分析1.引入庫2.讀入數據、效果驗證
    發表于 12-27 19:13 ?20次下載
    <b class='flag-5'>RT-Thread</b> Studio驅動SD卡

    RT-Thread全球技術大會:螢石研發團隊使用RT-Thread的技術挑戰

    RT-Thread全球技術大會:研發團隊使用RT-Thread的技術挑戰 ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 11:36 ?1308次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:螢石研發團隊使用<b class='flag-5'>RT-Thread</b>的技術挑戰

    RT-Thread全球技術大會:Kconfig在RT-Thread中的工作機制

    RT-Thread全球技術大會:Kconfig在RT-Thread中的工作機制 ? ? ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 14:49 ?1536次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:Kconfig在<b class='flag-5'>RT-Thread</b>中的工作機制

    RT-Thread全球技術大會:在RT-Thread上編寫測試用例

    RT-Thread全球技術大會:在RT-Thread上編寫測試用例 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 16:28 ?1472次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:在<b class='flag-5'>RT-Thread</b>上編寫測試用例

    RT-Thread全球技術大會:RT-Thread測試用例集合案例

    RT-Thread全球技術大會:RT-Thread測試用例集合案例 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 16:34 ?2098次閱讀
    <b class='flag-5'>RT-Thread</b>全球技術大會:<b class='flag-5'>RT-Thread</b>測試用例集合案例

    RT-Thread學習筆記 RT-Thread的架構概述

    RT-Thread 簡介 作為一名 RTOS 的初學者,也許你對 RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會逐漸發現 RT-Thread 的魅力和它相較于其他同類型 RTOS
    的頭像 發表于 07-09 11:27 ?4549次閱讀
    <b class='flag-5'>RT-Thread</b>學習筆記 <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread文檔_RT-Thread 簡介

    RT-Thread文檔_RT-Thread 簡介
    發表于 02-22 18:22 ?5次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 簡介

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread 潘多拉 STM32L475 上手指南
    發表于 02-22 18:23 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> 潘多拉 STM32L475 上手指南

    RT-Thread文檔_RT-Thread SMP 介紹與移植

    RT-Thread文檔_RT-Thread SMP 介紹與移植
    發表于 02-22 18:31 ?9次下載
    <b class='flag-5'>RT-Thread</b>文檔_<b class='flag-5'>RT-Thread</b> SMP 介紹與移植

    基于RT-Thread Studio學習

    前期準備:從官網下載 RT-Thread Studio,弄個賬號登陸,開啟rt-thread學習之旅。
    的頭像 發表于 05-15 11:00 ?3952次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio學習

    RT-Thread v5.0.2 發布

    RT-Thread 代碼倉庫地址: ●? https://github.com/RT-Thread/rt-thread RT-Thread 5.0.2 版本發布日志詳情: ●? htt
    的頭像 發表于 10-10 18:45 ?1480次閱讀
    <b class='flag-5'>RT-Thread</b> v5.0.2 發布
    主站蜘蛛池模板: 又黄又湿免费高清视频| 亚洲欧美国产双大乳头| 熟女人妻-蜜臀AV-首页| 天天久久狠狠色综合| 迅雷哥在线观看高清| 亚洲色噜噜狠狠站欲八| 中文字幕永久在线| AV天堂AV亚洲啪啪久久无码| 成人免费毛片观看| 国产一级特黄a大片99| 久久精品视频91| 欧美506070| 少男同志freedeos| 亚洲免费综合色视频| 2021国产在线视频| 成年人在线视频免费观看| 国产亚洲精品久久久久久鸭绿欲| 久久国内精品视频| 青青青青草原国产免费| 学生妹被爆插到高潮无遮挡| 中文字幕爆乳JULIA女教师| jealousvue成熟40岁| 国产午夜电影院| 玛雅成人网| 十九岁在线观看免费完整版电影| 亚洲卫视论坛| yellow免费观看直播| 好男人社区| 欧美巨大xxxx做受孕妇视频| 性欧美13处14处破| 69成人免费视频| 国产九色在线| 免费人妻AV无码专区五月| 忘忧草在线社区WWW日本直播| 在线看片成人免费视频| 都市妖奇谈有声| 久久久综合中文字幕久久| 肉奴隷 赤坂丽在线播放| 在线观看成人免费| 国产AV午夜精品一区二区入口| 久久久擼擼擼麻豆|