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

时间: 2024-07-28 19:02:35

C++学习之路: 线程封装(基于对象编程)的相关文章

JavaScript学习总结(九)——Javascript面向(基于)对象编程

一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫"原型对象",因此"类=原型对象" 二.类(原型对象)和对象(实例)的区别与联系 1.类(原型对象)是抽象,是概念的,代表一类事物. 2.对象是具体的,实际的,代表一个具体的事物. 3.类(原型对象)是对象实例的模板,对象实例是类的一个个体. 三.抽象的定义 在定义一个类时,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型(模板)

我的javascript学习之路(一)对象之基础

做了2个多月的ajax项目,对js的学习觉得了深入了不少,把自己的一些学习的经验贴出来,希望对初学者有所帮助,也希望大家能指出我的错误之处或者不当之处. javascript 是基于对象的语言,为什么这么说呢,需要仔细思考. js的单根继承体系需要仔细了解,我觉得在js的世界里本身没有类的概念,他只有对象Object,不像java语言本身就有了Object然后又有Class,js中我们可以自己根据他的语言来构件类这一对象,因为没有语言本身的支持,所以方法就各种各样了,但是只要我们掌握了js的本质

基于对象编程与面向对象编程(表达式计算器3)

基于对象编程与面向对象编程 我们的最终目的是用C++设计一个面向对象的表达式计算器,所以非常有必要弄清楚,什么是基于对象编程和面向对象的编程.而要弄清楚这一点,又要先弄明白什么是值语言,什么是对象语义 值语义:对象的拷贝与原对象无关,拷贝后与原对象脱离关系,互不影响.这种拷贝叫深拷贝.拷贝之后脱离关系,只要在拷贝的时候都为对象分配内存空间就行了.某种些情况下算是一种对资源的浪费 值语义例子 class Test { private: int * pNum_; public: Test(int n

《Essential C++》读书笔记 之 基于对象编程风格

<Essential C++>读书笔记 之 基于对象编程风格 2014-07-13 4.1 如何实现一个class 4.2 什么是Constructors(构造函数)和Destructors(析构函数) 4.3 何谓mutable(可变)和const(不变) 4.4 什么是this指针 4.5 Static Class Member(静态的类成员) 4.6 打造一个Iterator Class 4.7 合作关系必须建立在友谊的基础上 4.8 实现一个copy assignment operat

JavaScript基于对象编程

js面向对象特征介绍 javascript是一种面向(基于)对象的动态脚本语言,是一种基于对象(Object)和事件驱动(EventDirven)并具有安全性能的脚本语言.它具有面向对象语言所特有的各种特性,比如封装.继承及多态等.但对于大多数人说,我们只把javascript做为一个函数式语言,只把它用于一些简单的前端数据输入验证以及实现一些简单的页面动态效果等,我们没能完全把握动态语言的各种特性.在很多优秀的Ajax框架中,比如ExtJS.JQuery等,大量使用了javascript的面向

Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练

在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资料都可以查到,简单来说,就是将图像分成一个cell,通过对每个cell的像素进行梯度处理,进而根据梯度方向和梯度幅度来得到cell的图像特征.随后,将每个cell的图像特征连接起来,得到一个BLock的特征,进而得到一张图片的特征.Opencv当中自带HOG算法,可以直接调用,进行图像的特征提取.但

zigbee学习之路(十五):基于协议栈的按键实验

一.前言 经过上次的学习,相信大家已经初步学会使用zigbee协议进行发送和接受数据了.今天,我们要进行的实验是按键的实验,学会如何在协议栈里实现按键中断. 二.实验功能 在协议栈上实现按键中断,BUT1 按下,LED1 闪烁两次. 三.代码讲解 大家还记得,前面做过的按键实验是怎么配置的吗,其实基于zigbee的协议栈原理是差不多的,我们要对按键的接口和状态是差不多,TI已经为我们建立了专用的按键配置的代码文件,我们只要在此基础上修改就行了.先打开hel_key.c进行修改,下面是代码 #de

王亟亟的Python学习之路(八)-函数式编程,map(),reduce(),filter()

转载请注明出处:王亟亟的大牛之路 首先在这里祝愿大家,新年快乐,工作顺利,BUG少少!!! 本来说是在春节假期内继续维持着写文章的进度,但是还是偷懒了几天(打了4天SC2哈哈哈) 今天上的是关于Python的文章,毕竟在亲戚家拜年,懒得插各类手机调试什么的,况且确实好久没有弄Python了,就写了,废话不多,开始正题!! 函数式编程 函数是什么? 把复杂的操作化为简单的函数分解成简单的操作,这种操作就是面向过程,也就是C这类的实现的大体概念. 函数式是什么? 函数没有变量,任意一个函数,只要输入

JS面向(基于)对象编程--三大特征

抽象 在讲解面向对象编程的三大特征前,我们先了解什么叫抽象,在定义一个类时候,实际上就是把一类事物的共有的属性和行为提取出来,形成一个物理模型(模板).这种研究问题的方法称为抽象. 封装 什么是封装? 封装就是把抽象出来的属性和对属性的操作封装在一起,属性被保护在内部,程序的其它部分只有通过授权的操作(函数),才能对属性进行操作. 封装--访问控制修饰符 电视机的开关,对音量,颜色,频道的控制是公开的,谁都可以操作,但是对机箱后盖,主机板的操作却不是公开的,一般由专业维修人员来玩.那么在js中如