Boost中的function和bind功能,實現Linux下線程類封裝

最近在看陳碩的MUDUO網絡通訊庫的過程當中,發現做者大量使用了Boost::function以及Boost::bind功能,爲了可以正常的學習做者的代碼,決定先弄明白function以及bind的功能。ios

    Boost::Function 是對函數指針的對象化封裝,在概念上與廣義上的回調函數相似。相對於函數指針,function除了使用自由函數,還可使用函數對象,甚至是類的成員函數,這個就很強大了哈。windows

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):

>根據上述程序,咱們能夠發現,這樣咱們就不須要定義不少不少的類去繼承Thread類,而只須要寫好線程運行函數,set到Thread類中便可。不過也不能說利用虛函數留接口給用戶實現就很差,只不過如今多了一種方法。(陳碩很反對用虛函數做爲結構提供給用戶去作實現,可是我如今尚未切身的體會以爲那裏很差)

3. 總結

注:
1. 這邊只是簡單的用boost::function/bind結合pthread簡單的實現了一個本身封裝的線程類,

本身之前在windows下實現的基於虛函數的線程類實現:http://my.oschina.net/myspaceNUAA/blog/41014測試

2. boost::function/bind還有不少其餘高級用法,我這邊只是用來當作一個函數指針用了哈this

3. 測試環境:cygwin

相關文章
相關標籤/搜索