将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);
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
#ifndef THREAD_H_
#define THREAD_H_
class Thread
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
#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()
status = pthread_create(_pThread,NULL,thread_proxy_func,this);
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()
status = pthread_join(*_pThread,NULL);
err_abort("joining thread error...\n",status);
3.使用友元函數
友元函數的作用和靜态函數相同,都起到一個代理的作用。需要将對象的指針作為參數傳遞給這個友元函數,然後在友元函數中調用run函數。代碼如下,
由三個檔案構成:Thread.h(類的聲明檔案),Thread.cpp(類的實作檔案),main.cpp(測試檔案):
friend void * proxy_thread_func(void * args);
virtual ~Thread();
virtual void run(void) = 0;
void wait();
pthread_t * _thread;
void * proxy_thread_func(void * args);
void * proxy_thread_func(void * args)
Thread * _thread = static_cast<Thread *>(args);
_thread->run();
_thread = (pthread_t * )malloc(sizeof(pthread_t));
if(NULL == _thread)
error_abort("malloc failure...\n");
if(_thread != NULL)
delete _thread;
status = pthread_create(_thread,NULL,proxy_thread_func,this);
status = pthread_join(*_thread,NULL);
err_abort("joing thread...\n",status);
* main.c
class MyThread:public Thread
cout<<"I'm a littile tired. Sleep for a while..."<<endl;
t.start();
t.wait();
本文轉自hipercomer 51CTO部落格,原文連結:http://blog.51cto.com/hipercomer/941682