將Pthreads線程封裝爲抽象類,這樣用戶在使用線程時,只須要繼承一下這個抽象類,並實現相應的接口就能夠了。這樣作的好處是用戶能夠將注意力集中在線程所要執行的邏輯上,而不須要關注建立線程、銷燬線程等細節問題上。這裏給出兩種簡單的封裝方法,以供參考。
咱們抽象類的名稱爲Thread,其中有一個成員函數run,該函數爲的聲明形式爲:
void run() = 0;
即將該成員函數聲明爲純虛函數,用戶繼承此類必需要實現此成員函數。Thread中還有另一個成員函數start,該函數的聲明形式爲:
void start();
用戶在子類中調用start方法,將啓動線程,並在線程中執行run函數。
最常想到的方法就是在start方法中使用pthread_create建立一個線程,並調用run函數。以下面這樣的實現:
- void start()
- {
- int status;
- status = pthread_create(_pThread,NULL,Thread::run,NULL);
- if(status != 0)
- err_abort(「creating thread failure」,status);
- }
這樣編譯確定是不能經過的,這是由於pthread_create要求的線程例程的接口形式爲:
void *(*thread_routin)(void *args);
而上面代碼中提供的線程例程的接口形式爲:
void Thread::run()
顯然不符合要求的接口。
爲了可以在start中調用run函數,咱們不得不採用一種迂迴的方式。下面提供兩種方法:一種是使用靜態成員函數,另一種是使用友元函數。
靜態成員函數的做用域是全局的,而不單單侷限於某個函數中。靜態成員函數的實現方法和C語言中的普通函數相似,所以靜態函數沒有this指針,靜態函數只能操做靜態成員變量。之因此將靜態函數封裝到類中,在很大程度上也只是爲了知足面向對象的特性之一-----封裝性。
下面是一個簡單的使用靜態成員函數調用類中某個函數的例子,這個例子僅僅做爲一個引子:
- /*
- * main.cpp
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #include <iostream>
- #include <pthread.h>
- #include <time.h>
- #include "lc_error.h"
- using namespace std;
- class MyThread
- {
- public:
- void run()
- {
- fprintf(stdout,"I'm a little tired.Sleep for a while.\n");
- fflush(stdout);
- sleep(5);
- }
- static void * thread_proxy_func(void * args)
- {
- MyThread * pMyThread = static_cast<MyThread *>(args);
- pMyThread->run();
- return NULL;
- }
- virtual ~MyThread(){}
- };
- int main(int argc,char *argv[])
- {
- MyThread t;
- pthread_t thread;
- int status;
- status = pthread_create(&thread,NULL,MyThread::thread_proxy_func,(void *)&t);
- if(status != 0)
- err_abort("creating thread error...\n",status);
- status = pthread_join(thread,NULL);
- if(status != 0)
- err_abort("joining thread...\n",status);
- return 0;
- }
須要特別注意的是mian函數中使用pthread_create的執行例程爲MyThread類中的線程代理函數thread_proxy_func,在此函數中在調用run函數,這樣就順利的迂迴到了run函數。基於這種方法,咱們能夠用靜態函數來封裝一個簡單的抽象類,如下爲封裝的代碼,由三個文件構成:Thread.h(類的聲明文件),Thread.cpp(類的實現文件),main.cpp(測試文件):
- /*
- * Thread.h
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #ifndef THREAD_H_
- #define THREAD_H_
- #include "lc_error.h"
- #include <pthread.h>
- class Thread
- {
- public:
- Thread();
- ~Thread();
- virtual void run() = 0;
- void start();
- void wait();
- private:
- static void * thread_proxy_func(void *args);
- pthread_t * _pThread;
- };
- #endif /* THREAD_H_ */
- /*
- * Thread.cpp
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #include "Thread.h"
- Thread::Thread()
- {
- _pThread = (pthread_t *)malloc(sizeof(pthread_t));
- if(NULL == _pThread)
- error_abort("malloc error...\n");
- }
- Thread::~Thread()
- {
- if(NULL != _pThread)
- delete _pThread;
- }
- void Thread::start()
- {
- int status;
- status = pthread_create(_pThread,NULL,thread_proxy_func,this);
- if(status != 0)
- err_abort("creating thread...\n",status);
- }
- void * Thread::thread_proxy_func(void *args)
- {
- Thread * pThread = static_cast<Thread *>(args);
- pThread->run();
- return NULL;
- }
- void Thread::wait()
- {
- int status;
- status = pthread_join(*_pThread,NULL);
- if(status != 0)
- err_abort("joining thread error...\n",status);
- }
3.使用友元函數
友元函數的做用和靜態函數相同,都起到一個代理的做用。須要將對象的指針做爲參數傳遞給這個友元函數,而後在友元函數中調用run函數。代碼以下,
由三個文件構成:Thread.h(類的聲明文件),Thread.cpp(類的實現文件),main.cpp(測試文件):
- /*
- * Thread.h
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #ifndef THREAD_H_
- #define THREAD_H_
- #include "lc_error.h"
- #include <pthread.h>
- class Thread
- {
- public:
- friend void * proxy_thread_func(void * args);
- Thread();
- virtual ~Thread();
- void start();
- virtual void run(void) = 0;
- void wait();
- private:
- pthread_t * _thread;
- };
- void * proxy_thread_func(void * args);
- #endif /* THREAD_H_ */
- /*
- * Thread.cpp
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #include "Thread.h"
- void * proxy_thread_func(void * args)
- {
- Thread * _thread = static_cast<Thread *>(args);
- _thread->run();
- return NULL;
- }
- Thread::Thread()
- {
- _thread = (pthread_t * )malloc(sizeof(pthread_t));
- if(NULL == _thread)
- error_abort("malloc failure...\n");
- }
- Thread::~Thread()
- {
- if(_thread != NULL)
- delete _thread;
- }
- void Thread::start()
- {
- int status;
- status = pthread_create(_thread,NULL,proxy_thread_func,this);
- if(status != 0)
- err_abort("creating thread error...\n",status);
- }
- void Thread::wait()
- {
- int status;
- status = pthread_join(*_thread,NULL);
- if(status != 0)
- err_abort("joing thread...\n",status);
- }
- /*
- * main.c
- *
- * Created on: Jul 24, 2012
- * Author: lichao
- */
- #include "Thread.h"
- #include <iostream>
- #include <time.h>
- using namespace std;
- class MyThread:public Thread
- {
- public:
- void run()
- {
- cout<<"I'm a littile tired. Sleep for a while..."<<endl;
- sleep(5);
- }
- virtual ~MyThread(){}
- };
- int main(int argc,char *argv[])
- {
- MyThread t;
- t.start();
- t.wait();
- return 0;
- }