zoukankan      html  css  js  c++  java
  • 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
    ");
    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
    ", 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

  • 相关阅读:
    BEC listen and translation exercise 44
    中译英12
    BEC listen and translation exercise 43
    中译英11
    BEC listen and translation exercise 42
    中译英10
    BEC listen and translation exercise 41
    中译英9
    BEC listen and translation exercise 40
    中译英8
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4023369.html
Copyright © 2011-2022 走看看