回调函数

回调函数一般是在封装接口的时候,回调显得特别重要,我们首先假设有两个程序员在写代码,A程序员写底层驱动接口,B程序员写上层应用程序,然而此时底层驱动接口A有一个数据d需要传输给B,此时有两种方式: 
1、A将数据d存储好放在接口函数中,B自己想什么时候去读就什么时候去读,这就是我们经常使用的函数调用,此时主动权是B。 
2、A实现回调机制,当数据变化的时候才将通知B,你可以来读取数据了,然后B在用户层的回调函数中读取速度d,完成OK。此时主动权是A。 
很明显第一种方法太低效了,B根本就不知道什么时候该去调用接口函数读取数据d。而第二种方式由于B的读取数据操作是依赖A的,只有A叫B读数据,那么B才能读数据。也即是实现了中断读取。 
那么回调是怎么实现的呢,其实回调函数就是一个通过函数指针调用的函数。如果用户层B把函数的指针(地址)作为参数传递给底层驱动A,当这个指针在A中被用为调用它所指向的函数时,我们就说这是回调函数。 
注意:是在A中被调用,这里看到尽管函数是在B中,但是B却不是自己调用这个函数,而是将这个函数的函数指针通过A的接口函数传自A中了,由A来操控执行,这就是回调的意义所在。

同步回调和异步回调

首先,理解几个概念:

1.回调可以是同步也可以是异步

2.同步可以是单线程也可以是多线程

异步必须是多线程或多进程(每个进程可以是单线程) ==> 换句话说,异步必须依靠多线程或多进程才能完成

同步回调:把函数b传递给函数a。执行a的时候,回调了b,a要一直等到b执行完才能继续执行;
异步回调:把函数b传递给函数a。执行a的时候,回调了b,然后a就继续往后执行,b独自执行。

直接看例子
A.h

#ifndef A_H
#define A_H
typedef void (*pcb)(int a); //函数指针定义,后面可以直接使用pcb,方便
void SetCallBackFun(int a, pcb callback);
#endif

同步回调

synA.c

#include <stdio.h>
#include "A.h"//-----------------------底层实现A-----------------------------//留给应用层B的接口函数
void SetCallBackFun(int a, pcb callback)
{printf("A:start\n");callback(a);printf("A:end\n");
}

synB.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "A.h"
//-----------------------应用者B-------------------------------
void fCallBack(int a)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("B:start\n");printf("a = %d\n",a);sleep(5);printf("B:end\n");
}int main(void)
{SetCallBackFun(4,fCallBack);return 0;
}

异步回调

asynA.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include "A.h"//-----------------------底层实现A-----------------------------
typedef struct parameter{int a ;pcb callback;
}parameter;void* callback_thread(void *p1)//此处用的是一个线程
{//do somethingparameter* p = (parameter*)p1 ;sleep(5);p->callback(p->a);//函数指针执行函数,这个函数来自于应用层B}//留给应用层B的接口函数
void SetCallBackFun(int a, pcb callback)
{printf("A:start\n");parameter *p = malloc(sizeof(parameter)) ;p->a  = a;p->callback = callback;//创建线程pthread_t pid;pthread_create(&pid,NULL,callback_thread,(void *) p);printf("A:end\n");//阻塞,等待线程pid结束,才往下走pthread_join(pid,NULL);
}

asynB.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "A.h"
//-----------------------应用者B-------------------------------
void fCallBack(int a)       // 应用者增加的函数,此函数会在A中被执行
{//do somethingprintf("B:start\n");printf("a = %d\n",a);sleep(5);printf("B:end\n");
}int main(void)
{SetCallBackFun(4,fCallBack);return 0;
}

运行结果比较:

同步回调 异步回调
A:start
B:start
a = 4
B:end
A:end
A:start
A:end
B:start
a = 4
B:end

由执行结果可以看出:同步回调,A需要等待B执行完成才能执行A剩余的操作;异步回调,A刚执行B,不必等待B结束,就执行A剩余的操作,之后B的操作也随之end。
--------------------- 
作者:TWG8 
来源:CSDN 
原文:https://blog.csdn.net/qq_31930499/article/details/80654472 
版权声明:本文为博主原创文章,转载请附上博文链接!

回调函数 同步回调 异步回调相关推荐

  1. javascript的回调函数 同步 异步

    后一个任务等待前一个任务结束再执行.程序执行顺序与任务排列顺序一致的,同步的. 参考: http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%B ...

  2. 第三十一章 线程------GIL、线/近程池、异/同步、异步回调

    一.什么是GIL 官方解释:'''In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple ...

  3. html里的回调函数的作用域,异步与回调/函数的作用域链

    异步与回调/函数的作用域链 JavaScript 只在一个线程上运行,JavaScript 同时只能执行一个任务,其他任务都必须在后面排队等待. 这种模式的好处是实现起来比较简单,执行环境相对单纯:坏 ...

  4. 阻塞式回调函数和延迟式回调函数

    首先,有三种函数: 起始函数:大致可以等同于主函数 中间函数:中间函数把回调函数作为参数传递执行 回调函数:一个有独立功能的函数 怎么理解: 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里 ...

  5. 【Android 高性能音频】AAudio 音频流 PCM 采样 的 采样 缓冲 播放 的 连续机制 ( 数据回调机制 | 数据回调函数指针 | 实现数据回调函数 | 设置数据回调函数 )

    文章目录 I . AAudio 音频流 采样 缓冲 播放 的连续机制 II . AAudio 音频流 数据回调函数 函数指针类型定义 III . AAudio 音频流 数据回调函数 实现 IV . A ...

  6. 回调函数,回调函数,回调函数,什么是回调函数

    文章 目录 简介 一.回调函数是什么? 二.回调的demo 1.异步回调 2.安卓中的回调onclick 简介 问题引入: 在一个下载系统中,我要实现文件的下载和下载进度的显示.学习过面向对象的人来说 ...

  7. php paypal ipn回调,Paypal IPN / Webhook 异步回调流程是怎样的?

    里面提到的内容跟我遇到的差不多,我使用的是 Omnipay Paypal 包. 我之前直以为只要用户在 paypal 端完成支付,无论是否跳转回网站执行同步回调,IPN / Webhook 异步回调都 ...

  8. 【Android FFMPEG 开发】OpenSLES 播放音频 ( 创建引擎 | 输出混音设置 | 配置输入输出 | 创建播放器 | 获取播放/队列接口 | 回调函数 | 开始播放 | 激活回调 )

    文章目录 I . FFMPEG 播放视频流程 II . OpenSLES 播放音频流程 III . OpenSLES 播放参考 Google 官方示例 IV . OpenSL ES 播放代码 ( 详细 ...

  9. 回调函数、Java接口回调 总结

    回调函数 谈到回调,我们得先从回调函数说起,什么叫回调函数呢? 回调函数是什么? 百度百科的解释:回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针 ...

  10. 回调函数举例ajax,通过回调函数的理解来进一步理解ajax及其注意的用法

    一,再一次理解回调函数 (function($){ $.fn.shadow = function(opts){ //定义的默认的参数 var defaults = { copies: 5, opaci ...

最新文章

  1. mysql======基本的数据查询(1)
  2. 一文详解C++文件读写(FileStorage、txt)
  3. 企业 SOA 设计(1)–ESB 设计
  4. pandas的DataFrame用法
  5. su组件在什么窗口_Su与Rhino互导注意事项
  6. 九种破解Xp登录密码方法
  7. nginx 配置文件详解 深入理解nginx配置文件
  8. 第二节:使用IDEA创建React APP 并启动
  9. 于丹《庄子》心得讲稿-《大道与自然》
  10. 设置浏览器为单进程模式
  11. Android Tab 控件的使用
  12. 使用BeautifulSoup爬网页指定内容
  13. top命令显示参数详解
  14. QT读Word文档内容
  15. 论文笔记(Oriented R-CNN,ICCV2021)
  16. C# HttpUtility.UrlEncode 与 Java URLEncoder.encode的转换方法,李逵与李鬼
  17. Python计算期权隐含波动率
  18. 微服务开发(10)--Feign的使用
  19. 火狐浏览器下载文件时文件名乱码问题的解决
  20. php调用c dll,PHP调用DLL的方法

热门文章

  1. 文华财经期货量化策略抄底准确率高的指标公式,逃顶抄底精准共振起涨信号幅图指标
  2. 如何解决vscode频繁唤起git for Windows 导致电脑内存占用多大,cpu占用率飙升、风扇狂转问题
  3. 对thinkpad太失望了
  4. 百分制成绩转换为五级计分制时,90分以上为A,80~89分为B,70~79分为C,60~69分为D,0~59分为E。请把输入的百分之成绩转换为五级计分制输出。
  5. 过五关斩六将,一举拿下首张“金三银四”跳槽季的面试offer!熬夜成熊猫眼“筛选”出的面试真题
  6. c语言中recvfrom函数,C语言sendto()函数-经socket传送数据以及recvfrom函数《转》
  7. AI 脸部辨识情绪市场庞大 人类的情绪如何用机器解读?
  8. 手机中毒主要来自二维码
  9. phantom 输出中文乱码
  10. 带你了解区块链的三种类型