回调函数程序员
回调函数通常是在封装接口的时候,回调显得特别重要,咱们首先假设有两个程序员在写代码,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.回调能够是同步也能够是异步spa
2.同步能够是单线程也能够是多线程线程
异步必须是多线程或多进程(每一个进程能够是单线程) ==> 换句话说,异步必须依靠多线程或多进程才能完成指针
同步回调:把函数b传递给函数a。执行a的时候,回调了b,a要一直等到b执行完才能继续执行;blog
异步回调:把函数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 something printf("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 something parameter* 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 something printf("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。