【pthread系列-11】对Pthread线程进行简单的类封装
2013-02-27 11:10
447 查看
1.封装遇到的问题
将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指针,静态函数只能操作静态成员变量。之所以将静态函数封装到类中,在很大程度上也只是为了满足面向对象的特性之一-----封装性。
2.使用静态函数
下面是一个简单的使用静态成员函数调用类中某个函数的例子,这个例子仅仅作为一个引子:/* * 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; }
相关文章推荐
- 对Pthread线程进行简单的类封装
- [并发并行]_[pthread]_[对工作线程进行简单控制-暂停-继续-停止]
- c++ 11 多线线程系列-------- 一个最简单而且实用的线程池
- [并发并行]_[pthread]_[对工作线程进行简单控制-暂停-继续-停止]
- 线程模型、pthread 系列函数 和 简单多线程服务器端程序
- [POSIX线程模型]_[使用pthread对工作线程进行简单控制-暂停-继续-停止]
- posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
- pthread简单封装 线程退出
- linux网络编程之posix 线程(一):线程模型、pthread 系列函数 和 简单多线程服务器端程序
- c++ 11 多线线程系列-----------原子操作(atomic operation)
- C++简单封装pthread
- 【转】用Pthread创建线程的一个简单Demo
- java + 线程系列之showThread(一)----简单的线程创建方式有两种
- 使用闭包对setTimeout进行简单封装避免出错
- pthread 系列函数 和 简单多线程服务器端程序
- Webservice 封装为 Thread 在主线程进行调用--Android
- 简单说说android的线程封装
- 简单说说android的线程封装
- pthread 线程冲突一个简单例子
- 对libpq进行简单的c++封装