對Pthread線程進行簡單的類封裝

 

      1.封裝遇到的問題

       Pthreads線程封裝爲抽象類,這樣用戶在使用線程時,只須要繼承一下這個抽象類,並實現相應的接口就能夠了。這樣作的好處是用戶能夠將注意力集中在線程所要執行的邏輯上,而不須要關注建立線程、銷燬線程等細節問題上。這裏給出兩種簡單的封裝方法,以供參考。 ios

       咱們抽象類的名稱爲Thread,其中有一個成員函數run,該函數爲的聲明形式爲: ide

       void run() = 0; 函數

       即將該成員函數聲明爲純虛函數,用戶繼承此類必需要實現此成員函數。Thread中還有另一個成員函數start,該函數的聲明形式爲: 測試

       void start(); this

       用戶在子類中調用start方法,將啓動線程,並在線程中執行run函數。 spa

       最常想到的方法就是在start方法中使用pthread_create建立一個線程,並調用run函數。以下面這樣的實現: 線程

    

  
  
           
  
  
  1. void start() 
  2.  
  3.     { 
  4.  
  5.            int status; 
  6.  
  7.            status = pthread_create(_pThread,NULL,Thread::run,NULL); 
  8.  
  9.            if(status != 0) 
  10.  
  11.                   err_abort(「creating thread failure」,status); 
  12.  
  13.     } 

       這樣編譯確定是不能經過的,這是由於pthread_create要求的線程例程的接口形式爲: 代理

       void *(*thread_routin)(void *args); 指針

       而上面代碼中提供的線程例程的接口形式爲: orm

       void Thread::run()

       顯然不符合要求的接口。

       爲了可以在start中調用run函數,咱們不得不採用一種迂迴的方式。下面提供兩種方法:一種是使用靜態成員函數,另一種是使用友元函數。

       靜態成員函數的做用域是全局的,而不單單侷限於某個函數中。靜態成員函數的實現方法和C語言中的普通函數相似,所以靜態函數沒有this指針,靜態函數只能操做靜態成員變量。之因此將靜態函數封裝到類中,在很大程度上也只是爲了知足面向對象的特性之一-----封裝性。

2.使用靜態函數

       下面是一個簡單的使用靜態成員函數調用類中某個函數的例子,這個例子僅僅做爲一個引子:

 

  
  
           
  
  
  1. /* 
  2.  
  3.  * main.cpp 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13. #include <iostream> 
  14.  
  15. #include <pthread.h> 
  16.  
  17. #include <time.h> 
  18.  
  19. #include "lc_error.h" 
  20.  
  21.   
  22.  
  23. using namespace std; 
  24.  
  25.   
  26.  
  27. class MyThread 
  28.  
  29.  
  30. public
  31.  
  32.        void run() 
  33.  
  34.        { 
  35.  
  36.               fprintf(stdout,"I'm a little tired.Sleep for a while.\n"); 
  37.  
  38.               fflush(stdout); 
  39.  
  40.               sleep(5); 
  41.  
  42.        } 
  43.  
  44.        static void * thread_proxy_func(void * args) 
  45.  
  46.        { 
  47.  
  48.               MyThread * pMyThread = static_cast<MyThread *>(args); 
  49.  
  50.               pMyThread->run(); 
  51.  
  52.               return NULL; 
  53.  
  54.        } 
  55.  
  56.        virtual ~MyThread(){} 
  57.  
  58. }; 
  59.  
  60.   
  61.  
  62. int main(int argc,char *argv[]) 
  63.  
  64.  
  65.        MyThread t; 
  66.  
  67.        pthread_t thread
  68.  
  69.        int status; 
  70.  
  71.        status = pthread_create(&thread,NULL,MyThread::thread_proxy_func,(void *)&t); 
  72.  
  73.        if(status != 0) 
  74.  
  75.               err_abort("creating thread error...\n",status); 
  76.  
  77.        status = pthread_join(thread,NULL); 
  78.  
  79.        if(status != 0) 
  80.  
  81.               err_abort("joining thread...\n",status); 
  82.  
  83.        return 0; 
  84.  

       須要特別注意的是mian函數中使用pthread_create的執行例程爲MyThread類中的線程代理函數thread_proxy_func,在此函數中在調用run函數,這樣就順利的迂迴到了run函數。基於這種方法,咱們能夠用靜態函數來封裝一個簡單的抽象類,如下爲封裝的代碼,由三個文件構成:Thread.h(類的聲明文件),Thread.cpp(類的實現文件),main.cpp(測試文件):

 

  
  
           
  
  
  1.       /* 
  2.  
  3.  * Thread.h 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13.   
  14.  
  15. #ifndef THREAD_H_ 
  16.  
  17. #define THREAD_H_ 
  18.  
  19.   
  20.  
  21. #include "lc_error.h" 
  22.  
  23. #include <pthread.h> 
  24.  
  25.   
  26.  
  27. class Thread 
  28.  
  29.  
  30. public
  31.  
  32.        Thread(); 
  33.  
  34.        ~Thread(); 
  35.  
  36.        virtual void run() = 0; 
  37.  
  38.        void start(); 
  39.  
  40.        void wait();       
  41.  
  42. private
  43.     static void * thread_proxy_func(void *args); 
  44.  
  45.        pthread_t * _pThread; 
  46.  
  47. }; 
  48.  
  49.   
  50.  
  51.   
  52.  
  53. #endif /* THREAD_H_ */ 

 

 

  
  
           
  
  
  1. /* 
  2.  
  3.  * Thread.cpp 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13.   
  14.  
  15. #include "Thread.h" 
  16.  
  17.   
  18.  
  19. Thread::Thread() 
  20.  
  21.  
  22.        _pThread = (pthread_t *)malloc(sizeof(pthread_t)); 
  23.  
  24.        if(NULL == _pThread) 
  25.  
  26.               error_abort("malloc error...\n"); 
  27.  
  28.  
  29.   
  30.  
  31. Thread::~Thread() 
  32.  
  33.  
  34.        if(NULL != _pThread) 
  35.  
  36.               delete _pThread; 
  37.  
  38.  
  39.   
  40.  
  41. void Thread::start() 
  42.  
  43.  
  44.        int status; 
  45.  
  46.        status = pthread_create(_pThread,NULL,thread_proxy_func,this); 
  47.  
  48.  
  49.        if(status != 0) 
  50.  
  51.               err_abort("creating thread...\n",status); 
  52.  
  53.  
  54.   
  55.  
  56. void * Thread::thread_proxy_func(void *args) 
  57.  
  58.  
  59.        Thread * pThread = static_cast<Thread *>(args); 
  60.  
  61.        pThread->run(); 
  62.  
  63.        return NULL; 
  64.  
  65.  
  66.   
  67.  
  68. void Thread::wait() 
  69.  
  70.  
  71.        int status; 
  72.  
  73.        status = pthread_join(*_pThread,NULL); 
  74.  
  75.        if(status != 0) 
  76.  
  77.               err_abort("joining thread error...\n",status); 
  78.  

 

3.使用友元函數

       友元函數的做用和靜態函數相同,都起到一個代理的做用。須要將對象的指針做爲參數傳遞給這個友元函數,而後在友元函數中調用run函數。代碼以下,

由三個文件構成:Thread.h(類的聲明文件),Thread.cpp(類的實現文件),main.cpp(測試文件):

 

  
  
           
  
  
  1. /* 
  2.  
  3.  * Thread.h 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13.   
  14.  
  15. #ifndef THREAD_H_ 
  16.  
  17. #define THREAD_H_ 
  18.  
  19.   
  20.  
  21. #include "lc_error.h" 
  22.  
  23. #include <pthread.h> 
  24.  
  25.   
  26.  
  27. class Thread 
  28.  
  29.  
  30. public
  31.  
  32.        friend void * proxy_thread_func(void * args); 
  33.  
  34.        Thread(); 
  35.  
  36.        virtual ~Thread(); 
  37.  
  38.        void start(); 
  39.  
  40.        virtual void run(void) = 0; 
  41.  
  42.        void wait(); 
  43.  
  44. private
  45.  
  46.        pthread_t * _thread; 
  47.  
  48. }; 
  49.  
  50.   
  51.  
  52. void * proxy_thread_func(void * args); 
  53.  
  54.   
  55.  
  56. #endif /* THREAD_H_ */ 

 

 

  
  
           
  
  
  1. /* 
  2.  
  3.  * Thread.cpp 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13.   
  14.  
  15. #include "Thread.h" 
  16.  
  17.   
  18.  
  19. void * proxy_thread_func(void * args) 
  20.  
  21.  
  22.        Thread * _thread = static_cast<Thread *>(args); 
  23.  
  24.        _thread->run(); 
  25.  
  26.        return NULL; 
  27.  
  28.  
  29.   
  30.  
  31. Thread::Thread() 
  32.  
  33.  
  34.        _thread = (pthread_t * )malloc(sizeof(pthread_t)); 
  35.  
  36.        if(NULL == _thread) 
  37.  
  38.               error_abort("malloc failure...\n"); 
  39.  
  40.  
  41.   
  42.  
  43. Thread::~Thread() 
  44.  
  45.  
  46.        if(_thread != NULL) 
  47.  
  48.               delete _thread; 
  49.  
  50.  
  51.   
  52.  
  53. void Thread::start() 
  54.  
  55.  
  56.        int status; 
  57.  
  58.        status = pthread_create(_thread,NULL,proxy_thread_func,this); 
  59.  
  60.        if(status != 0) 
  61.  
  62.               err_abort("creating thread error...\n",status); 
  63.  
  64.  
  65.   
  66.  
  67. void Thread::wait() 
  68.  
  69.  
  70.        int status; 
  71.  
  72.        status = pthread_join(*_thread,NULL); 
  73.  
  74.        if(status != 0) 
  75.  
  76.               err_abort("joing thread...\n",status); 
  77.  

  
  
           
  
  
  1. /* 
  2.  
  3.  * main.c 
  4.  
  5.  * 
  6.  
  7.  *  Created on: Jul 24, 2012 
  8.  
  9.  *      Author: lichao 
  10.  
  11.  */ 
  12.  
  13.   
  14.  
  15. #include "Thread.h" 
  16.  
  17. #include <iostream> 
  18.  
  19. #include <time.h> 
  20.  
  21. using namespace std; 
  22.  
  23.   
  24.  
  25. class MyThread:public Thread 
  26.  
  27.  
  28. public
  29.  
  30.        void run() 
  31.  
  32.        { 
  33.  
  34.               cout<<"I'm a littile tired. Sleep for a while..."<<endl; 
  35.  
  36.               sleep(5); 
  37.  
  38.        } 
  39.  
  40.        virtual ~MyThread(){} 
  41.  
  42. }; 
  43.  
  44.   
  45.  
  46. int main(int argc,char *argv[]) 
  47.  
  48.  
  49.        MyThread t; 
  50.  
  51.        t.start(); 
  52.  
  53.        t.wait(); 
  54.  
  55.        return 0; 
  56.  
相關文章
相關標籤/搜索