回调函数、同步与异步调用

回调函数、同步与异步调用_第1张图片

正文


大家好,我是bug菌~

在嵌入式开发软件中回调函数是经常接触的一种软件设计方法,像我们的事件处理机制基本上都会使用到回调函数。

那么就抽了点时间来聊聊他们:

1

回调函数的理解

在C语言中,回调函数其实与函数指针的调用在语法上并没有太大的差异,而为什么叫回调函数主要还是从功能上给它起的名字,即这个函数会被"返回来调用"。

而这里所谓的“返回”就涉及到一个方向性问题,从哪里来到哪里去。而在软件中通常就是与“分层设计思想”挂钩的。

在软件设计领域分层设计方式是非常广泛的,在嵌入式中最简单的分层就是两层"驱动层"和“应用层”。

回调函数、同步与异步调用_第2张图片

当函数功能上进行分层以后不应该直接在底层驱动中直接调用应用层函数等,比如应用程序通过调用驱动层接口获得物理量数据,我们常规的做法大部分都是不断的轮询相应的API接口返回数据,这样可能会导致不断的IO操作,效率相对比较低下。

那么应用程序是否可以化主动为被动呢,一直舔狗实在是太累了?既然你现在不想搭理我,那等你准备好了,再来告诉我吧,到时候调用我给你的函数就可以了,这个函数已经放在了传给你的函数指针里了,那么这里应用程序所给的函数就是回调函数。

比如我们经常会在应用程序中查询按键是否被按下,然后得编写一大堆的时序等等,还与应用逻辑耦合在一起。

其实按键是是如何检测被按下的过程对于应用程序它并关心,底层程序查询确定好状态给应用程序一个是否按下的通知或者状态即可。

此时底层按键检测程序要通知应用程序,就可以通过相应的回调函数来通知应用层并处理即可。

如果还有点难理解,可以看看stm32使用hal库,你会发现在中断中有大量的回调函数指针被调用,其实回调函数的效果与中断服务函数的执行效果是类似的,hal库中使用回调函数的方式把中断的相关事件服务处理交给了用户自身来注册。

把中断看成一种事件类型,那么回调函数的使用其实就类似于一种事件驱动机制。

2

同步与异步调用

首先要理清楚这两种方式需要理解什么是同步和异步。

同步调用表示当调用一个底层接口,必须回调函数被执行完毕,不然该接口会一直处于堵塞状态没办法返回结果,且程序无法往下执行。

异步调用表示当调用一个底层接口以后,不需要等待回调函数执行完毕,便可以直接返回继续做下面的事情,最终底层准备好以后便会执行回调函数处理应用层事务,所以我们也称这种回调函数为异步回调函数。

而异步调用的好处在于调用函数不需要阻塞可以继续执行,从而大大提高程序运行效率,但由于异步回调函数在时间上是无序的,导致当我们需要异步调用函数能够顺序执行时便会存在难度,使得业务逻辑比较复杂,难以理解。

为了保证回调的有序性,就需要以上一次回调的结果作为本次异步调用的条件,导致代码一层嵌套一层非常的冗长,类似于ifelse里面再嵌套ifelse之势,所以也很多人称这种方式为 Callback hell(回调地狱)。

为了改善这种结构,通常会采用协程的概念去处理异步回调来规避该问题。

对于异步调用常与多线程进行结合,在另外一个线程中执行异步操作,然后调用回调函数返回结果并继续处理。

最后

      好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个~,

最后一个bug,bug菌唯一创作平台~

回调函数、同步与异步调用_第3张图片

推荐专辑  点击蓝色字体即可跳转

☞  MCU进阶专辑 c120a115e76e2644850c6a93bb40c3e4.gif

☞  嵌入式C语言进阶专辑 cdcbcd3b22c248f20f07f0ac3cca656f.gif

☞  “bug说”专辑 b2085b5cca4908e287dd3508b263caca.gif

☞ 专辑|Linux应用程序编程大全

☞ 专辑|学点网络知识

☞ 专辑|手撕C语言

☞ 专辑|手撕C++语言

☞ 专辑|经验分享

☞ 专辑|电能控制技术

☞ 专辑 | 从单片机到Linux

1eda69ee7f6f753491e07e6fef2457b4.gif

你可能感兴趣的:(嵌入式linux/RTOS,主流单片机开发(MCU),java,python,编程语言,c++,面试)