首页 > 代码库 > 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++学习之路: 线程封装(基于对象编程)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。