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

  • 相关阅读:
    酒里放茶,醉,未遂。
    利用自定义事件实现不同窗体间的通讯 Delphi篇
    主题:CS0016: 未能写入输出文件“c:&#92;WINDOWS&#92;Microsoft.NET&#92;***.dll”错误处理
    delphi點擊窗體最小化,關閉按鈕時的托盤圖標設置
    delphi制作程序啟動歡迎窗體
    那年 那雪
    DOL魔盘解决方案
    专家解密“艳照门”背后三大安全陷阱
    jQuery获取Select选择的Text和 Value(转)
    技术列传 guava cache
  • 原文地址:https://www.cnblogs.com/DLzhang/p/4023369.html
Copyright © 2011-2022 走看看