1.封装遇到的问题
将pthread线程封装为抽象类,这样用户在使用线程时,只需要继承一下这个抽象类,并实现相应的接口就可以了。这样做的好处是用户可以将注意力集中在线程所要执行的逻辑上,而不需要关注创建线程、销毁线程等细节问题上。
我们抽象类的名称为Thread,其中有一个成员函数run,该函数为的声明形式为:
void run() = 0;
即将该成员函数声明为纯虚函数,用户继承此类必须要实现此成员函数。Thread中还有另外一个成员函数start,该函数的声明形式为:
void start();
用户在子类中调用start方法,将启动线程,并在线程中执行run函数。
最常想到的方法就是在start方法中使用pthread_create创建一个线程,并调用run函数。如下面这样的实现:
| 1 2 3 4 5 6 7 8 9 | 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.使用静态函数
需要特别注意的是mian函数中使用pthread_create的执行例程为MyThread类中的线程代理函数thread_proxy_func,
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #ifndef THREAD_H #define THREAD_H #include <iostream> #include <pthread.h> using namespace std; class Thread { private:     //当前线程的线程ID     pthread_t tid;     //线程的状态     int threadStatus;     //获取执行方法的指针     static void* run0(void* pVoid);     static void * thread_proxy_func(void * args);     //内部执行方法     void* run1(); public:     //线程的状态-新建     static const int THREAD_STATUS_NEW = 0;     //线程的状态-正在运行     static const int THREAD_STATUS_RUNNING = 1;     //线程的状态-运行结束     static const int THREAD_STATUS_EXIT = -1;     //构造函数     Thread();     //线程的运行实体     virtual void run()=0;     //开始执行线程     bool start();     //获取线程ID     pthread_t getThreadID();     //获取线程状态     int getState();     //等待线程直至退出     void join();     //等待线程退出或者超时     void join(unsigned long millisTime); }; class MultiThread : public Thread { public:     void run()     {         int number = 0;         for (int i = 0; i < 10; i++)         {             cout << "Current number is " << number++;             cout << " PID is " << getpid() << " TID is " << getThreadID() << endl;             sleep(1);         }     } }; #endif | 
Thread.cpp
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include "thread.h" void* Thread::run0(void* pVoid) {     Thread* p = (Thread*) pVoid;     p->run1();     return p; } void* Thread::run1() {     threadStatus = THREAD_STATUS_RUNNING;     tid = pthread_self();     run();     threadStatus = THREAD_STATUS_EXIT;     tid = 0;     pthread_exit(NULL); } Thread::Thread() {     tid = 0;     threadStatus = THREAD_STATUS_NEW; } bool Thread::start() { 		int iRet = 0;     pthread_create(&tid, NULL, thread_proxy_func, this) == 0; } pthread_t Thread::getThreadID() {     return tid; } int Thread::getState() {     return threadStatus; } void Thread::join() {     if (tid > 0)     {         pthread_join(tid, NULL);     } } void * Thread::thread_proxy_func(void * args) {  		Thread * pThread = static_cast<Thread *>(args);  		pThread->run();   		return NULL;  } void Thread::join(unsigned long millisTime) {     if (tid == 0)     {         return;     }     if (millisTime == 0)     {         join();     }else     {         unsigned long k = 0;         while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)         {             usleep(100);             k++;         }     } } | 
main.cpp
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> #include <pthread.h> #include "thread.h" using namespace std; int main(int argv,char *argc) { 	MultiThread tt; 	tt.start(); 	tt.join(); 	return 0; } | 
3.使用友元函数
友元函数的作用和静态函数相同,都起到一个代理的作用。需要将对象的指针作为参数传递给这个友元函数,然后在友元函数中调用run函数。代码如下,
由三个文件构成:Thread.h(类的声明文件),Thread.cpp(类的实现文件),main.cpp(测试文件):
Thread.h
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #ifndef THREAD_H #define THREAD_H #include <iostream> #include <pthread.h> using namespace std; class Thread { private:     //当前线程的线程ID     pthread_t tid;     //线程的状态     int threadStatus;     //获取执行方法的指针     static void* run0(void* pVoid);     //static void * thread_proxy_func(void * args);     friend void * thread_proxy_func(void * args);     //内部执行方法     void* run1(); public:     //线程的状态-新建     static const int THREAD_STATUS_NEW = 0;     //线程的状态-正在运行     static const int THREAD_STATUS_RUNNING = 1;     //线程的状态-运行结束     static const int THREAD_STATUS_EXIT = -1;     //构造函数     Thread();     //线程的运行实体     virtual void run()=0;     //开始执行线程     bool start();     //获取线程ID     pthread_t getThreadID();     //获取线程状态     int getState();     //等待线程直至退出     void join();     //等待线程退出或者超时     void join(unsigned long millisTime); }; class MultiThread : public Thread { public:     void run()     {         int number = 0;         for (int i = 0; i < 10; i++)         {             cout << "Current number is " << number++;             cout << " PID is " << getpid() << " TID is " << getThreadID() << endl;             sleep(1);         }     } }; #endif | 
Thread.cpp
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | #include "thread.h" void* Thread::run0(void* pVoid) {     Thread* p = (Thread*) pVoid;     p->run1();     return p; } void* Thread::run1() {     threadStatus = THREAD_STATUS_RUNNING;     tid = pthread_self();     run();     threadStatus = THREAD_STATUS_EXIT;     tid = 0;     pthread_exit(NULL); } Thread::Thread() {     tid = 0;     threadStatus = THREAD_STATUS_NEW; } bool Thread::start() { 		int iRet = 0;     pthread_create(&tid, NULL, thread_proxy_func, this) == 0; } pthread_t Thread::getThreadID() {     return tid; } int Thread::getState() {     return threadStatus; } void Thread::join() {     if (tid > 0)     {         pthread_join(tid, NULL);     } } void * thread_proxy_func(void * args) {  		Thread * pThread = static_cast<Thread *>(args);  		pThread->run();   		return NULL;  } void Thread::join(unsigned long millisTime) {     if (tid == 0)     {         return;     }     if (millisTime == 0)     {         join();     }else     {         unsigned long k = 0;         while (threadStatus != THREAD_STATUS_EXIT && k <= millisTime)         {             usleep(100);             k++;         }     } } | 
main.cpp
| 1 2 3 4 5 6 7 8 9 10 11 12 | #include <iostream> #include "thread.h" using namespace std; int main(int argv,char *argc) { 	MultiThread tt; 	tt.start(); 	tt.join(); 	return 0; } | 
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | ANAME=server CC=g++ TMP_PROGS = main.cpp thread.cpp PROGS = $(TMP_PROGS) OBJS = $(PROGS:.cpp=.o) INCDIR=./ all: $(ANAME) $(ANAME): $(OBJS) 	@echo "--------------- .o to ELT " 	$(CC) -g $(TMP_PROGS) -o $@ -lpthread  .cpp.o: 	@echo "--------------- CPP to .o " 	$(CC) -g $(CFLAGS) -I$(INCDIR) -c  $< -o $@  -lpthread  clean: 	$(RM) $(ANAME) 	$(RM) *.o | 

发表评论
要发表评论,您必须先登录。