boost function和bind,实现Linux线程类封装

最近在看陈硕的MUDUO网络通信库的过程中,发现作者大量使用了Boost::function以及Boost::bind功能,为了能够正常的学习作者的代码,决定先弄明白function以及bind的功能。

Boost::Function 是对函数指针的对象化封装,在概念上与广义上的回调函数类似。相对于函数指针,function除了使用自由函数,还可以使用函数对象,甚至是类的成员函数,这个就很强大了哈。


1. 一个简单的示例代码

#include <boost/function.hpp>

#include <boost/bind.hpp>

#include <iostream>


using namespace std;


class TestA

{

       public:

              voidmethod()

              {

                     cout<<"TestA:method: no arguments"<<endl;

              }

 

              voidmethod(int a, int b)

              {

                     cout<<"TestA:method: with arguments"

                            <<"valueof a is:"<<a

                            <<"valueof b is "<<b <<endl;

              }

};


void sum(int a, int b)

{

       intsum = a + b;

       cout<<"sum:"<<sum<<endl;

}

 

int main()

{

       boost::function<void()>f;

       TestAtest;

 

       f= boost::bind(&TestA::method, &test);

       f();

 

       f= boost::bind(&TestA::method, &test, 1, 2);

       f();

 

       f= boost::bind(&sum, 1, 2);

       f();

}

 

输出结果:

Administrator@8bd5ec9e02074bf ~/source

$ ./BoostFunction.exe

TestA: method: no arguments

TestA: method: with argumentsvalue of ais:1value of b is 2

sum: 3

 

2. 应用:Thread封装

在实现自定义的线程类时,曾经这么干过:定义虚函数run(),用户自定义的CustomThread::Thread后,自己实现run()函数就OK了。当时觉得这么做也不错。

现在有了boost::function/boost::bind我们可以这么干:

定义一个线程类:

 

.h文件

 

#include <pthread.h>

#include <string>

#include <boost/function.hpp>

#include <boost/bind.hpp>


using namespace std;

class Thread

{

       typedefboost::function<void()> ThreadFun;

       public:

              Thread(constThreadFun& threadFun,const string& threadName = string());

              pid_t     getThreadId();

              string      getThreadName();

              int       start();

      

       private:

              staticvoid* startThread(void* thread);

 

       private:

              pthread_t      m_thread; //线程句柄

              pid_t             m_tid;    //线程ID

              string            m_strThreadName;    //线程名称

              bool              m_bStarted;         //线程是否启动

              ThreadFun    m_func;             //线程处理函数

};

 

.cpp文件

 

#include "thread.h"


Thread::Thread(const Thread::ThreadFun&threadFun, const string& threadName):

m_func(threadFun),m_strThreadName(threadName)

{

}


int Thread::start()

{

       m_tid= pthread_create(&m_thread, NULL, &startThread, this);

       return0;

}

 

void* Thread::startThread(void* obj)

{

 Thread* thread = static_cast<Thread*>(obj);

 thread->m_func();

 return NULL;

}

 

pid_t Thread::getThreadId()

{

       returnm_tid;

};

 

string     Thread::getThreadName()

{

       returnm_strThreadName;

}

 

测试程序

void ThreadProcess()

{

       intcount = 100;

       for(int i = 0; i < count; i++)

       {

           if (i % 10 == 0)    

              cout<<"\n";

           cout<<i<<"\t";

       }

}

 

int main()

{

       boost::function<void()>f;

       f= boost::bind(&ThreadProcess);  

       Thread thread(f, "ThreadTest");

       thread.start();

       sleep(1000*1000);

       return0;

}

 

输出结果(Cygwin):



>根据上述程序,我们可以发现,这样我们就不需要定义很多很多的类去继承Thread类,而只需要写好线程运行函数,setThread类中即可。不过也不能说利用虚函数留接口给用户实现就不好,只不过现在多了一种方法。(陈硕很反对用虚函数作为结构提供给用户去做实现,但是我现在还没有切身的体会觉得那里不好)

 

3. 总结

1. 这边只是简单的用boost::function/bind结合pthread简单的实现了一个自己封装的线程类,

2. boost::function/bind还有很多其他高级用法,我这边只是用来当做一个函数指针用了哈

3. 测试环境:cygwin

 

4.参考文献:

http://blog.csdn.net/benny5609/article/details/2324474

http://blog.csdn.net/Solstice/article/details/3066268



文章来源

http://my.csdn.net/my/mycsdn


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值