首页 > 代码库 > C++学习之路: 线程封装(基于对象编程)

C++学习之路: 线程封装(基于对象编程)

引言:

此次我们重新封装线程, 采用基于对象编程的方式,不用于面向对象编程中重定义虚函数的方式,这里我们用回调函数的方式。

Thread.h

 1 #ifndef THREAD_H_ 2 #define THREAD_H_ 3  4 #include <boost/noncopyable.hpp> 5 #include <functional> 6 #include <pthread.h> 7  8 class Thread : boost::noncopyable 9 {10 public:11     typedef std::function<void ()> ThreadCallback;12 13     Thread(ThreadCallback callback);14     ~Thread();15 16     void start();17     void join();18 19     static void *runInThread(void *);20 21 private:22     pthread_t threadId_;23     bool isRunning_;24     ThreadCallback callback_; //回调函数25 };26 27 28 29 #endif //THREAD_H_

 

可以看到没有重定义虚函数, 而是设置了一个函数适配器, 用于保存我们想要的业务逻辑。

直接用 静态函数 runInThread 调用 callback_即可。

 

Thread.cpp

 1 #include "Thread.h" 2  3 Thread::Thread(ThreadCallback callback) 4 : threadId_(0), 5   isRunning_(false), 6   callback_(std::move(callback)) 7 { 8  9 }10     11 Thread::~Thread()12 {13     if(isRunning_)14     {15         //detach16         pthread_detach(threadId_);17     }18 }19 20 void Thread::start()21 {22     pthread_create(&threadId_, NULL, runInThread, this);23     isRunning_ = true;24 }25 void Thread::join()26 {27     pthread_join(threadId_, NULL);28     isRunning_ = false;29 }30 31 void *Thread::runInThread(void *arg)32 {33     Thread *pt = static_cast<Thread*>(arg);34     pt->callback_(); //调用回调函数35 36     return NULL;37 }

以上 有几点经验处理, Google推荐 当Thread 这个类析构时,如果线程还没有执行完, 那么就detach。

并设置一个标志位 bool isRunning 标志线程是否启动。

 

测试代码

 1 #include "Thread.h" 2 #include <stdio.h> 3 #include <unistd.h> 4 using namespace std; 5  6 void foo() 7 { 8     while(1) 9     {10         printf("foo\n");11         sleep(1);12     }13 }14 15 16 17 int main(int argc, char const *argv[])18 {19     Thread t(&foo);20 21     t.start();22     t.join();23 24     return 0;25 }

可以看到, 当用基于对象编程时, 不需要在定义用户自己的类了, 只需在主函数传入一个函数适配器即可。 具体函数类型可以用bind来实现。

 

测试代码2

 1 #include "Thread.h" 2 #include <stdio.h> 3 #include <unistd.h> 4 using namespace std; 5  6 class Foo 7 { 8 public: 9     void foo(int i)10     {11         while(1)12         {13             printf("foo %d\n", i++);14             sleep(1);15         }16     }17 };18 19 20 21 int main(int argc, char const *argv[])22 {23     Foo f;24     int i = 34;25     Thread t(bind(&Foo::foo, &f, i));26 27     t.start();28     t.join();29 30     return 0;31 }

 

对于 类的成员函数 同理使用 大杀器bind

 

C++学习之路: 线程封装(基于对象编程)