【pthread系列-11】对Pthread线程进行简单的类封装

 

      1.封装遇到的问题

       Pthreads线程封装为抽象类,这样用户在使用线程时,只需要继承一下这个抽象类,并实现相应的接口就可以了。这样做的好处是用户可以将注意力集中在线程所要执行的逻辑上,而不需要关注创建线程、销毁线程等细节问题上。这里给出两种简单的封装方法,以供参考。

       我们抽象类的名称为Thread,其中有一个成员函数run,该函数为的声明形式为:

       void run() = 0;

       即将该成员函数声明为纯虚函数,用户继承此类必须要实现此成员函数。Thread中还有另外一个成员函数start,该函数的声明形式为:

       void start();

       用户在子类中调用start方法,将启动线程,并在线程中执行run函数。

       最常想到的方法就是在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);

       而上面代码中提供的线程例程的接口形式为:

       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.  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值