C語言 異步回調

本文主要講解如果實現回調,特別是在封裝接口的時候,回調顯得特別重要,我們首先假設有兩個程序員在寫代碼,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來操控執行,這就是回調的意義所在。
下面就通過一個例子來演示
首先寫A程序員的代碼

//-----------------------底層實現A-----------------------------
typedef void (*pcb)(int a); //函數指針定義,後面可以直接使用pcb,方便
typedef struct parameter{
    int a ;
    pcb callback;
}parameter; 

void* callback_thread(void *p1)//此處用的是一個線程
{
    //do something
    parameter* p = (parameter*)p1 ;
    while(1)
    {
        printf("GetCallBack print! \n");
        sleep(3);//延時3秒執行callback函數
        p->callback(p->a);//函數指針執行函數,這個函數來自於應用層B
    }
}

//留給應用層B的接口函數
extern SetCallBackFun(int a, pcb callback)
{
    printf("SetCallBackFun print! \n");
    parameter *p = malloc(sizeof(parameter)) ; 
    p->a  = 10;
    p->callback = callback;

    //創建線程
    pthread_t thing1;
    pthread_create(&thing1,NULL,callback_thread,(void *) p);
    pthread_join(thing1,NULL);
}

上面的代碼就是底層接口程序員A寫的全部代碼,留出接口函數SetCallBackFun即可

下面再實現應用者B的程序,B負責調用SetCallBackFun函數,以及增加一個函數,並將吃函數的函數指針通過SetCallBackFun(int a, pcb callback)的第二個參數pcb callback 傳遞下去。

//-----------------------應用者B-------------------------------
void fCallBack(int a)       // 應用者增加的函數,此函數會在A中被執行
{
    //do something
    printf("a = %d\n",a);
    printf("fCallBack print! \n");
}


int main(void)
{
    SetCallBackFun(4,fCallBack);

    return 0;
}

運行程序會看到

先會打印A程序的                 printf("GetCallBack print! \n");
然後等待3秒鐘纔會打印應用者B的    printf("fCallBack print! \n");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章