天天看點

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

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

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

1. 一個簡單的示例代碼

#include

#include

#include

using namespace std;

class TestA

{

public:

void method()

{

cout<

}

void method(int a, int b)

{

cout<

<

<

}

};

void sum(int a, int b)

{

int sum = a + b;

cout<

}

int main()

{

boost::function 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();

}

輸出結果:

[email protected] ~/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

#include

#include

#include

using namespace std;

class Thread

{

typedef boost::function 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_tm_thread; //線程句柄

pid_tm_tid;    //線程ID

stringm_strThreadName;    //線程名稱

boolm_bStarted;         //線程是否啟動

ThreadFunm_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(obj);

thread->m_func();

return NULL;

}

pid_t Thread::getThreadId()

{

return m_tid;

};

stringThread::getThreadName()

{

return m_strThreadName;

}

測試程式

void ThreadProcess()

{

int count = 100;

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

{

if (i % 10 == 0)

cout<

cout<

}

}

int main()

{

boost::function f;

f = boost::bind(&ThreadProcess);

Thread thread(f, "ThreadTest");

thread.start();

sleep(1000*1000);

return 0;

}

輸出結果(Cygwin):

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

>根據上述程式,我們可以發現,這樣我們就不需要定義很多很多的類去繼承Thread類,而隻需要寫好線程運作函數,set到Thread類中即可。不過也不能說利用虛函數留接口給使用者實作就不好,隻不過現在多了一種方法。(陳碩很反對用虛函數作為結構提供給使用者去做實作,但是我現在還沒有切身的體會覺得那裡不好)

3. 總結

注:

1. 這邊隻是簡單的用boost::function/bind結合pthread簡單的實作了一個自己封裝的線程類,

2. boost::function/bind還有很多其他進階用法,我這邊隻是用來當做一個函數指針用了哈

3. 測試環境:cygwin