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
转载于:https://www.cnblogs.com/DLzhang/p/4023369.html
C++学习之路: 线程封装(基于对象编程)相关推荐
- JavaScript学习总结(九)——Javascript面向(基于)对象编程
转载自 JavaScript学习总结(九)--Javascript面向(基于)对象编程 一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了 ...
- JavaScript基于对象编程
2019独角兽企业重金招聘Python工程师标准>>> JavaScript基于对象编程 1.JavaScript变量/函数声明在代码执行之前被解析,并且变量声明优先级高于函数声明. ...
- 《Essential C++》读书笔记 之 基于对象编程风格
<Essential C++>读书笔记 之 基于对象编程风格 2014-07-13 4.1 如何实现一个class 4.2 什么是Constructors(构造函数)和Destructor ...
- FPGA学习之路—应用程序—基于Verilog设计单总线8位ALU
FPGA学习之路--基于Verilog设计单总线8位ALU 定义 ALU(arithmetic and logic unit) 算术逻辑单元,简称ALU,是计算机的数学运算核心,也就是负责运算的组件, ...
- JavaScript学习总结(5)——Javascript面向(基于)对象编程
一.澄清概念 1.JS中"基于对象=面向对象" 2.JS中没有类(Class),但是它取了一个新的名字叫"原型对象",因此"类=原型对象" ...
- Python学习教程(Python学习路线):Day08-面向对象编程基础
Python学习教程(Python学习路线):面向对象编程基础 活在当下的程序员应该都听过"面向对象编程"一词,也经常有人问能不能用一句话解释下什么是"面向对象编程&qu ...
- 面向对象编程风格基于对象编程风格
本文主要通过实现Thread 类来展现两种编程风格的不同点. 很多人没有区分"面向对象"和"基于对象"两个不同的概念.面向对象的三大特点(封装,继承,多态)缺一 ...
- Kotlin学习之路(4)——类,对象和接口
类,对象和接口 之前的篇章已经简单的介绍过如何声明一个类,也知道了一些简单的主构造方法来声明方法和属性,以及使用枚举类. 类和接口 接口 和Java相同的是,我们同样用interface来定义一个接口 ...
- java 对象 线程安全_JAVA并发编程学习:构造线程安全的对象
设计线程安全的类 实例限制 当一个对象被另一个对象封装时,所有访问被被封装对象的代码路径就是全部可知的,这相比于让对象可被整个系统访问来说,更容易对代码路径进行分析.将数据封装在对象内部,把对数据的访 ...
最新文章
- python语法中infile语句_浅谈pymysql查询语句中带有in时传递参数的问题
- MD5加密解密帮助类
- Raspberry Pi 3B 安装NoneBot2
- 查询复旦大学往年的考研成绩
- 使用GDB跟踪redis源代码执行get命令的过程
- 市场的各大TWS蓝牙耳机芯片方案汇总
- 他,用了14年,从初代豆瓣工程师到AI公司CTO,创业心一直未变
- 计算机英特尔显卡在哪找,Win10英特尔显卡设置图标不见了该怎么办?
- <C语言程序实例>C语言实现菱形输出
- Digicert EV证书签名后出现“证书对于请求用法无效”的解决方案
- 01_Snaker简介
- Android 商品详情页
- 计算机组成原理笔记(王道考研) 第二章:数据的表示和运算1
- C语言rewind函数返回值为空,我用rewind函数没把指针直到开始,关闭文件然后打开就行。帮忙看看...
- 软件工程导论08-基于构件的软件开发
- Scrapy源码剖析前戏之Twisted使用
- windows10新版java环境配置2022年4月21H1版本
- 正味集团冲刺港股:年营收3.4亿杨声耀夫妇控制64%股权
- 英特尔AVX指令集解析
- Note For Linux By Jes(2)-Linux文件与目录管理