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:
		void method()
		{
			cout<<"TestA: method: no arguments"<<endl;
		}

		void method(int a, int b)
		{
			cout<<"TestA: method: with arguments"
				<<"value of a is:"<<a 
				<<"value of b is "<<b <<endl;
		}
};


void sum(int a, int b)
{
	int sum = a + b;
	cout<<"sum: "<<sum<<endl;
} 

int main()
{
	boost::function<void()> f;
	TestA test;

	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 a is: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
{
	typedef boost::function<void()> ThreadFun;
	public:
		Thread(const ThreadFun& threadFun,const string& threadName = string());
		pid_t     getThreadId();
		string	  getThreadName();
		int       start();
	
	private:
		static void* 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);
	return 0;
}

void* Thread::startThread(void* obj)
{
  Thread* thread = static_cast<Thread*>(obj);
  thread->m_func();
  return NULL;
}

pid_t Thread::getThreadId()
{
	return m_tid;
};

string	Thread::getThreadName()
{
	return m_strThreadName;
}

测试程序

void ThreadProcess()
{
	int count = 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);
	return 0;
}

输出结果(Cygwin):

Boost中的function和bind功能,实现Linux下线程类封装

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

3. 总结

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

自己以前在windows下实现的基于虚函数的线程类实现:http://my.oschina.net/myspaceNUAA/blog/41014

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

3. 测试环境:cygwin

4.参考文献:
http://blog.csdn.net/benny5609/article/details/2324474
http://blog.csdn.net/Solstice/article/details/3066268

你可能感兴趣的:(boost::bind,boost::function)