声明代码如下:
1 #ifndef THREAD_H 2 #define THREAD_H 3 4 #include "NonCopyable.h" 5 #include <pthread.h> 6 #include <sys/types.h> 7 8 class Thread : NonCopyable 9 { 10 public: 11 Thread(); 12 virtual ~Thread(); 13 14 void start(); 15 void join(); 16 17 pthread_t getThreadId() { return _threadId; } 18 virtual void run() = 0; 19 20 private: 21 static void *func(void *arg); 22 23 pthread_t _threadId; 24 bool _isRun; 25 }; 26 27 #endif
为了调用pthread_create创建线程,我们往里面注册的不能是一个成员函数,因为成员函数含有一个隐式参数,导致函数的指针类型并不是void *(*start_routine) (void *),所以我们采用了static函数。
static函数无法访问某一对象的成员,所以我们在调用pthread_create时,将this指针作为回调函数的参数。
这个Thread不提供detach函数,因为我们在析构函数中做了如下的处理,如果Thread对象析构,线程还在运行,那么需要将Thread设置为detach状态。
大部分逻辑都是固定的,用户只需要改变run里面的代码即可,于是我们将run设置为纯虚函数,让用户继承Thread类。
cpp代码实现如下:
1 #include "Thread.h" 2 #include <iostream> 3 #include <assert.h> 4 #include <unistd.h> 5 #include <sys/syscall.h> 6 using namespace std; 7 8 Thread::Thread() 9 :_threadId(0), 10 _isRun(false) 11 { } 12 13 Thread::~Thread() 14 { 15 if(_isRun) 16 pthread_detach(_threadId); 17 } 18 19 20 void *Thread::func(void *arg) 21 { 22 Thread *p = static_cast<Thread *>(arg); 23 p->run(); 24 return NULL; 25 } 26 27 28 void Thread::start() 29 { 30 pthread_create(&_threadId, NULL, Thread::func, this); 31 _isRun = true; 32 } 33 34 void Thread::join() 35 { 36 assert(_isRun); 37 pthread_join(_threadId, NULL); 38 _isRun = false; 39 }
我们采用继承的方式使用这个类。测试代码如下:
1 #include "Thread.h" 2 #include <iostream> 3 #include <unistd.h> 4 using namespace std; 5 6 class MyThread : public Thread 7 { 8 public: 9 void run() 10 { 11 cout << "foo" << endl; 12 } 13 }; 14 15 int main(int argc, char const *argv[]) 16 { 17 MyThread t; 18 t.start(); 19 20 t.join(); 21 22 return 0; 23 }