在嵌入式開(kāi)發(fā)軟件中回調(diào)函數(shù)是經(jīng)常接觸的一種軟件設(shè)計(jì)方法,像我們的事件處理機(jī)制基本上都會(huì)使用到回調(diào)函數(shù)。
那么就抽了點(diǎn)時(shí)間來(lái)聊聊他們:
什么是回調(diào)函數(shù)?
在C語(yǔ)言中,回調(diào)函數(shù)其實(shí)與函數(shù)指針的調(diào)用在語(yǔ)法上并沒(méi)有太大的差異,而為什么叫回調(diào)函數(shù)主要還是從功能上給它起的名字,即這個(gè)函數(shù)會(huì)被"返回來(lái)調(diào)用"。
而這里所謂的“返回”就涉及到一個(gè)方向性問(wèn)題,從哪里來(lái)到哪里去。而在軟件中通常就是與“分層設(shè)計(jì)思想”掛鉤的。
在軟件設(shè)計(jì)領(lǐng)域分層設(shè)計(jì)方式是非常廣泛的,在嵌入式中最簡(jiǎn)單的分層就是兩層"驅(qū)動(dòng)層"和“應(yīng)用層”。
當(dāng)函數(shù)功能上進(jìn)行分層以后不應(yīng)該直接在底層驅(qū)動(dòng)中直接調(diào)用應(yīng)用層函數(shù)等,比如應(yīng)用程序通過(guò)調(diào)用驅(qū)動(dòng)層接口獲得物理量數(shù)據(jù),我們常規(guī)的做法大部分都是不斷的輪詢(xún)相應(yīng)的API接口返回?cái)?shù)據(jù),這樣可能會(huì)導(dǎo)致不斷的IO操作,效率相對(duì)比較低下。
那么應(yīng)用程序是否可以化主動(dòng)為被動(dòng)呢,一直舔狗實(shí)在是太累了?既然你現(xiàn)在不想搭理我,那等你準(zhǔn)備好了,再來(lái)告訴我吧,到時(shí)候調(diào)用我給你的函數(shù)就可以了,這個(gè)函數(shù)已經(jīng)放在了傳給你的函數(shù)指針里了,那么這里應(yīng)用程序所給的函數(shù)就是回調(diào)函數(shù)。
比如我們經(jīng)常會(huì)在應(yīng)用程序中查詢(xún)按鍵是否被按下,然后得編寫(xiě)一大堆的時(shí)序等等,還與應(yīng)用邏輯耦合在一起。
其實(shí)按鍵是是如何檢測(cè)被按下的過(guò)程對(duì)于應(yīng)用程序它并關(guān)心,底層程序查詢(xún)確定好狀態(tài)給應(yīng)用程序一個(gè)是否按下的通知或者狀態(tài)即可。
此時(shí)底層按鍵檢測(cè)程序要通知應(yīng)用程序,就可以通過(guò)相應(yīng)的回調(diào)函數(shù)來(lái)通知應(yīng)用層并處理即可。
如果還有點(diǎn)難理解,可以看看stm32使用hal庫(kù),你會(huì)發(fā)現(xiàn)在中斷中有大量的回調(diào)函數(shù)指針被調(diào)用,其實(shí)回調(diào)函數(shù)的效果與中斷服務(wù)函數(shù)的執(zhí)行效果是類(lèi)似的,hal庫(kù)中使用回調(diào)函數(shù)的方式把中斷的相關(guān)事件服務(wù)處理交給了用戶(hù)自身來(lái)注冊(cè)。
把中斷看成一種事件類(lèi)型,那么回調(diào)函數(shù)的使用其實(shí)就類(lèi)似于一種事件驅(qū)動(dòng)機(jī)制。
同步與異步調(diào)用
首先要理清楚這兩種方式需要理解什么是同步和異步。
同步調(diào)用表示當(dāng)調(diào)用一個(gè)底層接口,必須回調(diào)函數(shù)被執(zhí)行完畢,不然該接口會(huì)一直處于堵塞狀態(tài)沒(méi)辦法返回結(jié)果,且程序無(wú)法往下執(zhí)行。
異步調(diào)用表示當(dāng)調(diào)用一個(gè)底層接口以后,不需要等待回調(diào)函數(shù)執(zhí)行完畢,便可以直接返回繼續(xù)做下面的事情,最終底層準(zhǔn)備好以后便會(huì)執(zhí)行回調(diào)函數(shù)處理應(yīng)用層事務(wù),所以我們也稱(chēng)這種回調(diào)函數(shù)為異步回調(diào)函數(shù)。
而異步調(diào)用的好處在于調(diào)用函數(shù)不需要阻塞可以繼續(xù)執(zhí)行,從而大大提高程序運(yùn)行效率,但由于異步回調(diào)函數(shù)在時(shí)間上是無(wú)序的,導(dǎo)致當(dāng)我們需要異步調(diào)用函數(shù)能夠順序執(zhí)行時(shí)便會(huì)存在難度,使得業(yè)務(wù)邏輯比較復(fù)雜,難以理解。
為了保證回調(diào)的有序性,就需要以上一次回調(diào)的結(jié)果作為本次異步調(diào)用的條件,導(dǎo)致代碼一層嵌套一層非常的冗長(zhǎng),類(lèi)似于ifelse里面再嵌套ifelse之勢(shì),所以也很多人稱(chēng)這種方式為 Callback hell(回調(diào)地獄)。
為了改善這種結(jié)構(gòu),通常會(huì)采用協(xié)程的概念去處理異步回調(diào)來(lái)規(guī)避該問(wèn)題。對(duì)于異步調(diào)用常與多線(xiàn)程進(jìn)行結(jié)合,在另外一個(gè)線(xiàn)程中執(zhí)行異步操作,然后調(diào)用回調(diào)函數(shù)返回結(jié)果并繼續(xù)處理。
原文標(biāo)題:嵌入式軟件中回調(diào)函數(shù)同步與異步調(diào)用
文章出處:【微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19104瀏覽量
304796 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7604瀏覽量
136683 -
回調(diào)函數(shù)
+關(guān)注
關(guān)注
0文章
87瀏覽量
11554
原文標(biāo)題:嵌入式軟件中回調(diào)函數(shù)同步與異步調(diào)用
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論