C++ 异步回调

上一文中讲了C语言通过函数指针实现异步回调,本文讲解C++类中实现线程回调

C++类中实现线程回调

本文继续讨论C++中实现回调,由于C++中有类,而C语言中的回调函数不能直接定义为成员函数,所以就很麻烦了,下面将讨论解决办法。
首先知道静态成员函数是全局的,也就是类的,因此推测可以用静态成员函数来实现回调机制。这里补充一下关于类中静态成员的知识

静态成员测试

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

class xiabo_C{
public:
    xiabo_C():a(10),d(8)
    {
        printf("I am xiabo_C() function\n");
    }
    static int sfunc(); //静态成员函数也遵循public,private,protected访问规则
    int func(void);

public:
    int a;
    static int b ;      //此处不能初始化
    static const int c = 9;//只有静态常量才能直接初始化
    const  int d;
};

int  xiabo_C::b = 11;   //静态成员变量的初始化只能这样,不能在构造中初始化

int xiabo_C::sfunc(){   //!!!静态成员函数在类外部实现时,千万不要加static,不要写成了static int sfunc(){},这是内外部的静态C函数
    //xiabo::a = 11;    //error   静态成员函数不能应用非静态成员
    xiabo_C::b = 12;
    printf("I am static member function,b = %d\n",xiabo_C::b );
    return 0;
}
static int sfunc1(){
    printf("I am static function, not member function \n" );
    return 0;
}
int xiabo_C::func(void){
    xiabo_C::b = 12;
    xiabo_C::sfunc();
    sfunc1();
    return 0;
}
int main(void ){
    xiabo_C xiabo;
    xiabo.func();
    xiabo_C::sfunc();  //静态成员函数是类的,不是某个对象的,引用必须通过类名来访问
    getchar();
    return 0;
}

下面就使用静态成员函数实现回调,同样的和C语言中一样的结构,只不过改成类

测试静态成员函数实现回调

//-------------
class xiabo2_C{
public:
    typedef int (*pcb)(int a);
    typedef struct parameter{
        int a ;
        pcb callback;
    }parameter; 
    xiabo2_C():m_a(1){

    }
    //普通函数
    void GetCallBack(parameter* p)  // 写回调者实现的回调函数
    {
        m_a = 2;
        //do something
        while(1)
        {
            printf("GetCallBack print! \n");
            _sleep(2000);
            p->callback(p->a);
        }
    }
    int SetCallBackFun(int a, pcb callback)
    {
        printf("SetCallBackFun print! \n");
        parameter *p = new parameter ; 
        p->a  = 10;
        p->callback = callback;
        GetCallBack(p);
        return 0;
    }

public:
    int m_a;
};

class xiabo2Test_C{
public:
    xiabo2Test_C():m_b(1){

    }
    static int fCallBack(int a)         // 应用者实现的回调函数,静态成员函数,但是不能访问类中非静态成员了,破坏了类的结构
    {
        //do something
        //m_b = a;      // 不能访问类中非静态成员了,破坏了类的结构,应用者使用很麻烦
        printf("a = %d\n",a);
        printf("fCallBack print! \n");
        return 0;
    }
public:
    int m_b;
};
int main(void ){
    //test_statichunc();
    xiabo2_C xiabo2;
    xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);
    getchar();
    return 0;
}

这里写图片描述
虽然这种方法实现了回调,但是应用者那是1万个不情愿,尼玛为了用个回调,我类类里面的非静态成员什么都不能用了,还不如不回调呢,让我直接调用吧。那有没有一种方法两全其美呢,有!那是必须的。

测试非静态成员函数实现回调

//-------------------
template<typename Tobject,typename Tparam>
class xiabo3_C{
    typedef void (Tobject::*Cbfun)(Tparam* );
public:
    bool Exec(Tparam* pParam);
    void Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam);

private:
    Cbfun pCbfun;
    Tobject* m_pInstance;
};

template<typename Tobject,typename Tparam>
void xiabo3_C<Tobject,Tparam>::Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam){
    printf("Set print!\n");
    m_pInstance = pInstance;
    (pInstance->*pFun)(pParam);     //可以直接在这里回调传过来的函数指针
    pCbfun = pFun;
}
template<typename Tobject,typename Tparam>
bool xiabo3_C<Tobject,Tparam>::Exec(Tparam* pParam){
    printf("Exec print!\n");
    (m_pInstance->*pCbfun)(pParam);//也可以在这里回调传过来的函数指针
    return true;
}

class xiabo3Test_C{
public:
    xiabo3Test_C():m_N(13){

    }
    void fCallBack(int *p){
        printf("fCallBack : Sum = m_N + *p = %d\n",*p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa\n");
    }

private:
    int m_N;
};
int main(void ){
    xiabo3_C<xiabo3Test_C,int> xiabo3;
    xiabo3Test_C xiabo3Test;
    int p = 13;
    xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
    xiabo3.Exec(&p);
    getchar();
    return 0;
}

这里写图片描述

上面可以看出成员函数Exec和Set都仅仅是个函数,那万一我需要的是线程呢?问题又来了,创建线程的线程Wrapper又不能是非静态成员函数。例如下面这样写就不行

class  xiabo4_C{
public:
    xiabo4_C():m_N(1){

    }
    void funThreadAlgorithm(void);
    void CreatAlgorithmThread(void);
public:

private:
    int m_N;
};
void xiabo4_C::funThreadAlgorithm(void){
}
void xiabo4_C::CreatAlgorithmThread(void){
    HANDLE handle1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm,0,0,NULL);  
    CloseHandle(handle1);//!!error  
}

当然我们可以将线程的Wrapper改成static成员函数就可以,但是代价是不能访问类中的非静态成员。

class  xiabo4_C{
public:
    xiabo4_C():m_N(1){

    }
    static void funThreadAlgorithm(void);
    void CreatAlgorithmThread(void);
public:

private:
    int m_N;
};
void xiabo4_C::funThreadAlgorithm(void){
    while(1)
    {
        _sleep(3000);
        printf("I am a static meeber function! I can not access the member\n");
    }
}
void xiabo4_C::CreatAlgorithmThread(void){
    HANDLE handle1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm,0,0,NULL);  
    CloseHandle(handle1);
}

上述代码就实现了静态成员函数用于线程wrapper,但是又想要两全其美怎么办,仔细分析,之所以不能将非静态成员函数用于线程wrapper,那是因为没有为线程wrapper提供this指针。那么既然是这样,我们在创建线程的时候将对象的this指针传入线程wrapper中,然后线程wrapper就可以调用非静态成员函数啦!哈哈 想想应该是这样的哦,试一试。

类中定义线程

//--------------
//类中定义线程
class  xiabo4_C{
public:
    struct ThreadParam{
        xiabo4_C* pthis;
        int a ;
        int b ;
    };//根据线程参数自定义结构

public:
    xiabo4_C():m_N(1){

    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //非静态实现
    void CreatAlgorithm2Thread(int a ,int b);
    static void funThreadAlgorithm2(ThreadParam* p);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(int a ,int b){
        printf("ThreadFunc : I am ThreadFunc,I am a member function! I can access all the member ,HaHa...\n");
    }

private:
    int m_N;
};

void xiabo4_C::CreatAlgorithm2Thread(int a ,int b){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    p->b     = b;
    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm2,p,0,NULL); 
    CloseHandle(handle2);
}
void xiabo4_C::funThreadAlgorithm2(ThreadParam* p){
    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d, p->b = %d \n",p->a,p->b);
    p->pthis->ThreadFunc(p->a,p->b);
}

这里写图片描述
实验结果表明猜想正确,ThreadFunc()函数才是我们真正要实现的线程执行函数了!
下面实现最后一步,实现C++异步回调,无论是程序员A(实现回调底层)还是程序员B(应用者回调者,姑且这么定义吧我也不知道怎么定义好),都能在很好的使用类中成员,不会有什么静态与非静态成员的阻挡了。

类中定义线程,并实现回调

//--------------
//类中定义线程,并实现回调
//A程序员
template<typename Tobject,typename Tparam>
class  xiabo5_C{
public:
    struct ThreadParam{
        xiabo5_C* pthis;
        Tparam a ;
    };//根据线程参数自定义结构
    typedef void (Tobject::*Cbfun)(Tparam );
public:
    xiabo5_C():m_N(1){

    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //非静态实现
    void CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a );
    static void funCallbackThread(ThreadParam* p);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(Tparam a );  //线程执行函数

private:
    int m_N;
    Cbfun pCbfun;
    Tobject* m_pInstance;
};
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>:: CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a ){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    m_pInstance = pInstance;
    pCbfun = pFun;

    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funCallbackThread,p,0,NULL);   
    CloseHandle(handle2);
}
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>::funCallbackThread(ThreadParam* p){
    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d, p->b = %d \n",p->a);
    p->pthis->ThreadFunc(p->a);
}
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>::ThreadFunc(Tparam a ){
    printf("ThreadFunc : I am ThreadFunc,I am a member function! I can access all the member ,HaHa...\n");
    printf("ThreadFunc : m_N = %d \n",m_N);
    while(1)
    {
        Sleep(2000);
        (m_pInstance->*pCbfun)(a);
    }
}
//B程序员
class xiabo5Test_C{
public:
    xiabo5Test_C():m_N(55){

    }
    void fCallBack(int p){
        printf("fCallBack : Sum = m_N + *p = %d\n",p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa...\n");
    }
public:

private:
    int m_N;
};


int main(void ){
    //测试静态成员函数
    //test_statichunc();

    //测试静态成员函数,用于回调
    //xiabo2_C xiabo2;
    //xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);

    //测试非静态成员函数,用于回调,good
    //xiabo3_C<xiabo3Test_C,int> xiabo3;
    //xiabo3Test_C xiabo3Test;
    //int p = 13;
    //xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
    //xiabo3.Exec(&p);

    //类中定义线程
    //xiabo4_C xiabo4;
    //xiabo4.CreatAlgorithm2Thread(1,2);

    //类中定义线程,并实现回调
    xiabo5_C<xiabo5Test_C,int> xiabo5;
    xiabo5Test_C xiabo5Test;
    int p = 45;
    xiabo5.CreateCallbackThread(&xiabo5Test,&xiabo5Test_C::fCallBack,p);


    xiabo5_C<xiabo5Test_C,int> xiabo51;
    xiabo5Test_C xiabo5Test1;
    int p1 = -45;
    xiabo51.CreateCallbackThread(&xiabo5Test1,&xiabo5Test_C::fCallBack,p1);

    getchar();
    return 0;
}

这里写图片描述

附件

VS2012版本测试代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
    #include <windows.h>
#else
    #include <pthread.h>
#endif

#ifdef _MSC_VER
    #define mysleep(n)  Sleep(n)
#else
    #define mysleep(n)  sleep(n/1000)
#endif

using namespace std;


class xiabo_C{
public:
    xiabo_C():a(10),d(8)
    {
        printf("I am xiabo_C() function\n");
    }
    static int sfunc(); //静态成员函数也遵循public,private,protected访问规则
    int func(void);

public:
    int a;
    static int b ;      //此处不能初始化
    static const int c = 9;//只有静态常量才能直接初始化
    const  int d;
};

int  xiabo_C::b = 11;   //静态成员变量的初始化只能这样,不能在构造中初始化

int xiabo_C::sfunc(){   //!!!静态成员函数在类外部实现时,千万不要加static,不要写成了static int sfunc(){},这是内外部的静态C函数
    //xiabo::a = 11;    //error   静态成员函数不能应用非静态成员
    xiabo_C::b = 12;
    printf("I am static member function,b = %d\n",xiabo_C::b );
    return 0;
}
static int sfunc1(){
    printf("I am static function, not member function \n" );

    return 0;
}
int xiabo_C::func(void){
    xiabo_C::b = 12;
    xiabo_C::sfunc();
    sfunc1();
    return 0;
}
void test_statichunc(void){
    xiabo_C xiabo;
    xiabo.func();
    xiabo_C::sfunc();  //静态成员函数是类的,不是某个对象的,引用必须通过类名来访问

}
//-------------
class xiabo2_C{
public:
    typedef int (*pcb)(int a);
    typedef struct parameter{
        int a ;
        pcb callback;
    }parameter; 
    xiabo2_C():m_a(1){

    }
    //普通函数
    void GetCallBack(parameter* p)  // 写回调者实现的回调函数
    {
        m_a = 2;
        //do something
        while(1)
        {
            printf("GetCallBack print! \n");
            mysleep(2000);
            p->callback(p->a);
        }
    }
    int SetCallBackFun(int a, pcb callback)
    {
        printf("SetCallBackFun print! \n");
        parameter *p = new parameter ; 
        p->a  = 10;
        p->callback = callback;
        GetCallBack(p);
        return 0;
    }

public:
    int m_a;
};

class xiabo2Test_C{
public:
    xiabo2Test_C():m_b(1){

    }
    static int fCallBack(int a)         // 应用者实现的回调函数,静态成员函数,但是不能访问类中非静态成员了,破坏了类的结构
    {
        //do something
        //m_b = a;      // 不能访问类中非静态成员了,破坏了类的结构,应用者使用很麻烦
        printf("a = %d\n",a);
        printf("fCallBack print! \n");
        return 0;
    }
public:
    int m_b;
};

//-------------------
template<typename Tobject,typename Tparam>
class xiabo3_C{
    typedef void (Tobject::*Cbfun)(Tparam* );
public:
    bool Exec(Tparam* pParam);
    void Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam);

private:
    Cbfun pCbfun;
    Tobject* m_pInstance;
};

template<typename Tobject,typename Tparam>
void xiabo3_C<Tobject,Tparam>::Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam){
    printf("Set print!\n");
    m_pInstance = pInstance;
    (pInstance->*pFun)(pParam);     //可以直接在这里回调传过来的函数指针
    pCbfun = pFun;
}
template<typename Tobject,typename Tparam>
bool xiabo3_C<Tobject,Tparam>::Exec(Tparam* pParam){
    printf("Exec print!\n");
    (m_pInstance->*pCbfun)(pParam);//也可以在这里回调传过来的函数指针
    return true;
}

class xiabo3Test_C{
public:
    xiabo3Test_C():m_N(13){

    }
    void fCallBack(int *p){
        printf("fCallBack : Sum = m_N + *p = %d\n",*p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa...\n");
    }

private:
    int m_N;

};

//--------------
//类中定义线程,并实现回调
class  xiabo4_C{
public:
    struct ThreadParam{
        xiabo4_C* pthis;
        int a ;
        int b ;
    };//根据线程参数自定义结构

public:
    xiabo4_C():m_N(1){

    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //静态实现
    void CreatAlgorithmThread(void);
    static void *funThreadAlgorithm(void* p);  //静态成员函数实现线程Wrapper
    //非静态实现
    void CreatAlgorithm2Thread(int a ,int b);
    static void *funThreadAlgorithm2(void* param);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(int a ,int b){
        printf("ThreadFunc : I am ThreadFunc,I am a member function! I can access all the member ,HaHa...\n");
        printf("ThreadFunc : m_N = %d \n",m_N);
    }

private:
    int m_N;
};

void xiabo4_C::CreatAlgorithmThread(void){  //静态实现
#ifdef _MSC_VER
    HANDLE handle1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm,0,0,NULL);  
    CloseHandle(handle1);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funThreadAlgorithm,(void *) 0);
    pthread_join(thing1,NULL);
#endif
}
void* xiabo4_C::funThreadAlgorithm(void* p){
    while(1)
    {
        mysleep(2000);
        printf("I am a static meeber function! I can not access the member\n");
    }
}

void xiabo4_C::CreatAlgorithm2Thread(int a ,int b){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    p->b     = b;
#ifdef _MSC_VER
    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm2,p,0,NULL); 
    CloseHandle(handle2);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funThreadAlgorithm2,(void *) p);
    pthread_join(thing1,NULL);
#endif
}
void* xiabo4_C::funThreadAlgorithm2(void* param){
    ThreadParam* p = (ThreadParam*)param;

    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d, p->b = %d \n",p->a,p->b);
    p->pthis->ThreadFunc(p->a,p->b);
    return 0;
}

//--------------
//类中定义线程,并实现回调
//A程序员
template<typename Tobject,typename Tparam>
class  xiabo5_C{
public:
    struct ThreadParam{
        xiabo5_C* pthis;
        Tparam a ;
    };//根据线程参数自定义结构
    typedef void (Tobject::*Cbfun)(Tparam );
public:
    xiabo5_C():m_N(1){
        printf("xiabo5_C : xiabo5_C()\n");
    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //非静态实现
    void CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a );
    static void* funCallbackThread(void* param);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(Tparam a );  //线程执行函数

private:
    int m_N;
    Cbfun pCbfun;
    Tobject* m_pInstance;
};
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>:: CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a ){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    m_pInstance = pInstance;
    pCbfun = pFun;

#ifdef _MSC_VER
    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funCallbackThread,p,0,NULL);   
    CloseHandle(handle2);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funCallbackThread,(void *) p);
    //pthread_join(thing1,NULL);  //这儿不能阻塞
#endif
}
template<typename Tobject,typename Tparam>
void* xiabo5_C<Tobject,Tparam>::funCallbackThread(void* param){
    ThreadParam* p  = (ThreadParam*)param;
    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d\n",p->a);
    p->pthis->ThreadFunc(p->a);
    return 0;
}
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>::ThreadFunc(Tparam a ){

    printf("ThreadFunc : I am ThreadFunc,I am a member function! I can access all the member ,HaHa...\n");
    printf("ThreadFunc : m_N = %d \n",m_N);
    while(1)
    {
        mysleep(2000);
        (m_pInstance->*pCbfun)(a);
    }
}
//B程序员
class xiabo5Test_C{
public:
    xiabo5Test_C():m_N(55){

    }
    void fCallBack(int p){
        printf("fCallBack : Sum = m_N + *p = %d\n",p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa...\n");
    }
public:

private:
    int m_N;
};


int main(void ){
    //测试静态成员函数
    //test_statichunc();

    //测试静态成员函数,用于回调
    //xiabo2_C xiabo2;
    //xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);

    //测试非静态成员函数,用于回调,good
    //xiabo3_C<xiabo3Test_C,int> xiabo3;
    //xiabo3Test_C xiabo3Test;
    //int p = 13;
    //xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
    //xiabo3.Exec(&p);

    //类中定义线程
    //xiabo4_C xiabo4;
    //xiabo4.CreatAlgorithm2Thread(1,2);

    //类中定义线程,并实现回调
    xiabo5_C<xiabo5Test_C,int> xiabo5;
    xiabo5Test_C xiabo5Test;
    int p = 45;
    xiabo5.CreateCallbackThread(&xiabo5Test,&xiabo5Test_C::fCallBack,p);


    xiabo5_C<xiabo5Test_C,int> xiabo51;
    xiabo5Test_C xiabo5Test1;
    int p1 = -45;
    xiabo51.CreateCallbackThread(&xiabo5Test1,&xiabo5Test_C::fCallBack,p1);
    //getchar();
    return 0;
}

GCC版本

增加了线程ID打印

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
    #include <windows.h>
#else
    #include <pthread.h>
#endif

#ifdef _MSC_VER
    #define mysleep(n)  Sleep(n)
#else
    #define mysleep(n)  sleep(n/1000)
#endif

using namespace std;


class xiabo_C{
public:
    xiabo_C():a(10),d(8)
    {
        printf("I am xiabo_C() function\n");
    }
    static int sfunc(); //静态成员函数也遵循public,private,protected访问规则
    int func(void);

public:
    int a;
    static int b ;      //此处不能初始化
    static const int c = 9;//只有静态常量才能直接初始化
    const  int d;
};

int  xiabo_C::b = 11;   //静态成员变量的初始化只能这样,不能在构造中初始化

int xiabo_C::sfunc(){   //!!!静态成员函数在类外部实现时,千万不要加static,不要写成了static int sfunc(){},这是内外部的静态C函数
    //xiabo::a = 11;    //error   静态成员函数不能应用非静态成员
    xiabo_C::b = 12;
    printf("I am static member function,b = %d\n",xiabo_C::b );
    return 0;
}
static int sfunc1(){
    printf("I am static function, not member function \n" );

    return 0;
}
int xiabo_C::func(void){
    xiabo_C::b = 12;
    xiabo_C::sfunc();
    sfunc1();
    return 0;
}
void test_statichunc(void){
    xiabo_C xiabo;
    xiabo.func();
    xiabo_C::sfunc();  //静态成员函数是类的,不是某个对象的,引用必须通过类名来访问

}
//-------------
class xiabo2_C{
public:
    typedef int (*pcb)(int a);
    typedef struct parameter{
        int a ;
        pcb callback;
    }parameter; 
    xiabo2_C():m_a(1){

    }
    //普通函数
    void GetCallBack(parameter* p)  // 写回调者实现的回调函数
    {
        m_a = 2;
        //do something
        while(1)
        {
            printf("GetCallBack print! \n");
            mysleep(2000);
            p->callback(p->a);
        }
    }
    int SetCallBackFun(int a, pcb callback)
    {
        printf("SetCallBackFun print! \n");
        parameter *p = new parameter ; 
        p->a  = 10;
        p->callback = callback;
        GetCallBack(p);
        return 0;
    }

public:
    int m_a;
};

class xiabo2Test_C{
public:
    xiabo2Test_C():m_b(1){

    }
    static int fCallBack(int a)         // 应用者实现的回调函数,静态成员函数,但是不能访问类中非静态成员了,破坏了类的结构
    {
        //do something
        //m_b = a;      // 不能访问类中非静态成员了,破坏了类的结构,应用者使用很麻烦
        printf("a = %d\n",a);
        printf("fCallBack print! \n");
        return 0;
    }
public:
    int m_b;
};

//-------------------
template<typename Tobject,typename Tparam>
class xiabo3_C{
    typedef void (Tobject::*Cbfun)(Tparam* );
public:
    bool Exec(Tparam* pParam);
    void Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam);

private:
    Cbfun pCbfun;
    Tobject* m_pInstance;
};

template<typename Tobject,typename Tparam>
void xiabo3_C<Tobject,Tparam>::Set(Tobject *pInstance,Cbfun pFun,Tparam* pParam){
    printf("Set print!\n");
    m_pInstance = pInstance;
    (pInstance->*pFun)(pParam);     //可以直接在这里回调传过来的函数指针
    pCbfun = pFun;
}
template<typename Tobject,typename Tparam>
bool xiabo3_C<Tobject,Tparam>::Exec(Tparam* pParam){
    printf("Exec print!\n");
    (m_pInstance->*pCbfun)(pParam);//也可以在这里回调传过来的函数指针
    return true;
}

class xiabo3Test_C{
public:
    xiabo3Test_C():m_N(13){

    }
    void fCallBack(int *p){
        printf("fCallBack : Sum = m_N + *p = %d\n",*p + m_N);
        printf("fCallBack print! I am a member function! I can access all the member ,HaHa...\n");
    }

private:
    int m_N;

};

//--------------
//类中定义线程
class  xiabo4_C{
public:
    struct ThreadParam{
        xiabo4_C* pthis;
        int a ;
        int b ;
    };//根据线程参数自定义结构

public:
    xiabo4_C():m_N(1){

    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //静态实现
    void CreatAlgorithmThread(void);
    static void *funThreadAlgorithm(void* p);  //静态成员函数实现线程Wrapper
    //非静态实现
    void CreatAlgorithm2Thread(int a ,int b);
    static void *funThreadAlgorithm2(void* param);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(int a ,int b){
        printf("ThreadFunc : I am ThreadFunc,I am a member function! I can access all the member ,HaHa...\n");
        printf("ThreadFunc : m_N = %d \n",m_N);
    }

private:
    int m_N;
};

void xiabo4_C::CreatAlgorithmThread(void){  //静态实现
#ifdef _MSC_VER
    HANDLE handle1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm,0,0,NULL);  
    CloseHandle(handle1);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funThreadAlgorithm,(void *) 0);
    pthread_join(thing1,NULL);
#endif
}
void* xiabo4_C::funThreadAlgorithm(void* p){
    while(1)
    {
        mysleep(2000);
        printf("I am a static meeber function! I can not access the member\n");
    }
}

void xiabo4_C::CreatAlgorithm2Thread(int a ,int b){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    p->b     = b;
#ifdef _MSC_VER
    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funThreadAlgorithm2,p,0,NULL); 
    CloseHandle(handle2);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funThreadAlgorithm2,(void *) p);
    pthread_join(thing1,NULL);
#endif
}
void* xiabo4_C::funThreadAlgorithm2(void* param){
    ThreadParam* p = (ThreadParam*)param;

    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d, p->b = %d \n",p->a,p->b);
    p->pthis->ThreadFunc(p->a,p->b);
    return 0;
}

//--------------
//类中定义线程,并实现回调
//A程序员
template<typename Tobject,typename Tparam>
class  xiabo5_C{
public:
    struct ThreadParam{
        xiabo5_C* pthis;
        Tparam a ;
    };//根据线程参数自定义结构
    typedef void (Tobject::*Cbfun)(Tparam );
public:
    xiabo5_C():m_N(1){
        printf("xiabo5_C : xiabo5_C()\n");
    }
    void print(void){
        printf("print : m_N = %d \n",m_N);
    }
    //非静态实现
    void CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a );
    static void* funCallbackThread(void* param);  //非静态成员函数实现线程Wrapper
    void ThreadFunc(Tparam a );  //线程执行函数

private:
    int m_N;
    Cbfun pCbfun;
    Tobject* m_pInstance;
};
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>:: CreateCallbackThread(Tobject *pInstance,Cbfun pFun,Tparam a ){
    ThreadParam* p = new ThreadParam;
    p->pthis = this;
    p->a     = a;
    m_pInstance = pInstance;
    pCbfun = pFun;

#ifdef _MSC_VER
    HANDLE handle2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)funCallbackThread,p,0,NULL);   
    CloseHandle(handle2);
#else
    pthread_t thing1;
    pthread_create(&thing1,NULL,&funCallbackThread,(void *) p);
    //pthread_join(thing1,NULL); //warning !! can not be join !!!
#endif
}
template<typename Tobject,typename Tparam>
void* xiabo5_C<Tobject,Tparam>::funCallbackThread(void* param){
    ThreadParam* p  = (ThreadParam*)param;
    printf("I am a static meeber function! I can not access the member\n");
    printf("But I can call a member func ,I can instigate ThreadFunc ,ThreadFunc can access all member\n");
    printf("ThreadParam p->a = %d\n",p->a);
    p->pthis->ThreadFunc(p->a);
    return 0;
}
template<typename Tobject,typename Tparam>
void xiabo5_C<Tobject,Tparam>::ThreadFunc(Tparam a ){
    printf("I am ThreadFunc,I am a member function and access all the member ,HaHa...\n");
    //printf("%d ThreadFunc : m_N = %d \n",m_N);
    while(1)
    {
        const pthread_t me = pthread_self();
        mysleep(a*1000);
        (m_pInstance->*pCbfun)(me);
    }
}
//B程序员
class xiabo5Test_C{
public:
    xiabo5Test_C():m_N(0){

    }
    void fCallBack(int p){
        printf("Thread ID = %d fCallBack : Sum = m_N + *p = %d\n",p,p + m_N);
        //printf("fCallBack print! I am a member function! I can access all the member ,HaHa...\n");
    }
public:

private:
    int m_N;
};


int main(void ){
    //测试静态成员函数
    //test_statichunc();

    //测试静态成员函数,用于回调
    //xiabo2_C xiabo2;
    //xiabo2.SetCallBackFun(5,xiabo2Test_C::fCallBack);

    //测试非静态成员函数,用于回调,good
    //xiabo3_C<xiabo3Test_C,int> xiabo3;
    //xiabo3Test_C xiabo3Test;
    //int p = 13;
    //xiabo3.Set(&xiabo3Test,&xiabo3Test_C::fCallBack,&p); //
    //xiabo3.Exec(&p);

    //类中定义线程
    //xiabo4_C xiabo4;
    //xiabo4.CreatAlgorithm2Thread(1,2);

    //类中定义线程,并实现回调
    xiabo5_C<xiabo5Test_C,int> xiabo5;
    xiabo5Test_C xiabo5Test;
    int p = 2;
    xiabo5.CreateCallbackThread(&xiabo5Test,&xiabo5Test_C::fCallBack,p);


    xiabo5_C<xiabo5Test_C,int> xiabo51;
    xiabo5Test_C xiabo5Test1;
    int p1 = 4;
    xiabo51.CreateCallbackThread(&xiabo5Test1,&xiabo5Test_C::fCallBack,p1);
    getchar();
    return 0;
}

参考

博客
博客
知道

  • 14
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
C++ 中,多线程异步回调函数可以通过使用 std::thread 和 std::async 实现。 std::thread 是 C++11 中引入的一个线程库,它可以创建一个新的线程来执行函数。例如,以下代码创建了一个新线程并执行了一个函数: ``` void myFunction() { // 执行一些操作 } int main() { std::thread t(myFunction); t.join(); // 等待线程执行完毕 return 0; } ``` std::async 也是 C++11 中引入的另一个库,它可以异步地执行一个函数并返回一个 std::future 对象,该对象可以用于获取异步函数的返回值。例如,以下代码使用 std::async 异步地执行一个函数: ``` int myFunction() { // 执行一些操作 return 42; } int main() { std::future<int> result = std::async(std::launch::async, myFunction); // 执行一些其他操作 int value = result.get(); // 等待异步函数执行完毕并获取返回值 return 0; } ``` 在多线程中使用异步回调函数时,可以将回调函数作为参数传递给异步函数,在异步函数完成后调用回调函数。例如,以下代码异步执行一个函数并在完成后调用回调函数: ``` void myCallback(int result) { // 处理异步函数的结果 } void myFunction(std::function<void(int)> callback) { // 执行一些操作 int result = 42; callback(result); // 调用回调函数 } int main() { std::function<void(int)> callback = myCallback; std::async(std::launch::async, myFunction, callback); // 执行一些其他操作 return 0; } ``` 在上面的代码中,myFunction 接受一个 std::function 对象作为回调函数,并在异步执行完毕后调用该函数。在 main 函数中,我们创建了一个 std::function 对象并将其传递给异步函数。在异步函数执行完毕后,myCallback 函数将被调用,并传递异步函数的结果作为参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值