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         //detach
16         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

 

posted @ 2014-10-13 23:18  tilly_chang  阅读(309)  评论(0编辑  收藏  举报