使用C++11的thread取代QThread
因为在做的工程项目里使用了Qt,而实际上不涉及到屏幕显示,工程代码里使用了QThread,且没有使用Qt核心的信号与槽,为了以后移植准备使用更加通用的C++11 stl中的thread取代QThread。
下面是一些测试过程,因为没有为这个小测试建一个版本控制,所以为了能记录每步测试修改,这里将编写代码编写博客,开始吧。
#include <iostream>
#include <thread>
#include <chrono>
#include <functional> using namespace std; class MyThread
{
public:
MyThread()
{
thread t([this]()-> void { run(); });
t.detach();
} public:
void run()
{
for(int i=;i<;i++)
{
cout<<"Hello Nelson!"<<endl;
std::this_thread::sleep_for(std::chrono::milliseconds());
}
}
}; int main(int argc,char *argv[])
{ MyThread mythread; cout<<"main thread is over"<<endl; return ;
}
上面代码运行环境,Ubuntu 16.04.4 g++版本:gcc version 5.4.0
先使用VS2008编译不行,VS2010编译不行,主要报错是说没有std::thread,这里有个文档,里面有VS各个版本对C++11支持说明,https://blogs.msdn.microsoft.com/vcblog/2011/09/12/c11-features-in-visual-c-11/ (C++11 Features in Visual C++11)。
上述代码的编译指令是这样的:g++ -std=c++11 -pthread test.cpp -o test
注意指定标准C++11和-pthread线程库链接选项,test.c代码里没有#include <pthread> ,如果去掉-phtread编译,结果提示undefined reference to `pthread_create'。运行test,结果如下:

子线程建立后,主线程和子线程的线程调度是不确定的,索引多执行几次test后,结果会不一样。因为thread对象调用了detach,所以子线程运行状态与线程对象完全无关,thread t在构造函数执行完了之后就消亡了。如果验证子线程在主线程结束了以后还在运行呢?在子线程里向文件里写内容。
#include <iostream>
#include <thread>
#include <chrono>
#include <functional>
#include <fstream> using namespace std; class MyThread
{
public:
MyThread()
{
thread t([this]()-> void { run(); });
t.detach();
} public:
void run()
{
fstream f;
f.open("test.txt",ios::out|ios::trunc); for(int i=;i<;i++)
{
cout<<"Hello Nelson!"<<endl;
f<<"Write One Line\n";
std::this_thread::sleep_for(std::chrono::milliseconds());
f<<"Write The Other Line\n";
}
f.close();
}
}; int main(int argc,char *argv[])
{ MyThread mythread; cout<<"main thread is over"<<endl; std::this_thread::sleep_for(std::chrono::milliseconds()); //delay for file create return ;
}
编译运行,结果如下:

和想象中的结果不一致,预期是子线程独立运行,在文档中写入多行文字,而且结果中居然一行也没有显示。修改主线程休眠时间,由10ms改为10s,结果如下:

这就说明文件读写是很正常的。
主线程关闭时也关闭了子线程?不然无法理解Hello Nelson不接着打印,同时文件写操作内容不见了。文件写操作内容不见了则可以说明这种情况下,子线程内部的操作都是不安全的,不可预期的。
下面测试让主线程主动关闭子线程(通过控制变量bRun做到的),这才是需要的线程基本控制。
#include <iostream>
#include <thread>
#include <chrono>
#include <functional>
#include <fstream> using namespace std; class MyThread
{
private:
bool bRun; public:
void DisableThreadRun()
{
bRun = false;
} public:
MyThread()
{
bRun = true; thread t([this]()-> void { run(); });
t.detach();
} public:
void run()
{
fstream f;
f.open("test.txt",ios::out|ios::trunc); while(bRun)
{
for(int i=;i<;i++)
{
cout<<"Hello Nelson!"<<endl;
f<<"Write One Line\n";
std::this_thread::sleep_for(std::chrono::milliseconds());
f<<"Write The Other Line\n";
}
f.flush();
}
f.close();
cout<<"sub thread is running out"<<endl;
}
}; int main(int argc,char *argv[])
{
MyThread mythread; std::this_thread::sleep_for(std::chrono::milliseconds()); //delay for file create
mythread.DisableThreadRun();
std::this_thread::sleep_for(std::chrono::milliseconds()); cout<<"main thread is over"<<endl; return ;
}
测试结果如下

主要是子线程函数,这里使用lambda表达式用起来就是非常的爽,【capture】属性中填入this(参见上一篇博客),lambda表达式中就可以获得所在类里的所有权限了,直接调用类成员方法run。开起来是不是跟QThread里的Run一样。
使用C++11的thread去掉QThread很容易了吧。
使用C++11的thread取代QThread的更多相关文章
- C++11之thread线程
今天由于项目需求(其实是某门课的一个大作业,不好意思说出口啊...),想要使用多线程.相信大家一般用的是linux上的POSIX C或windows上的线程库,然而这些线程库以来于特定系统,并不“标准 ...
- QThread 爬坑之旅(三种办法解决QObject: Cannot create children for a parent that is in a different thread)
Cannot create children for a parent that is in a different thread. 在Qt的官方文档,大家知道有两种方式使用QThread. You ...
- 漫谈C++11 Thread库之原子操作
我在之前一篇博文<漫谈C++11 Thread库之使写多线程程序>中,着重介绍了<thread>头文件中的std::thread类以及其上的一些基本操作,至此我们动手写多线程程 ...
- C++11 多线程编程 使用lambda创建std::thread (生产/消费者模式)
要写个tcp server / client的博客,想着先写个c++11多线程程序.方便后面写博客使用. 目前c++11中写多线程已经很方便了,不用再像之前的pthread_create,c++11中 ...
- mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)
我正在安装 mingw-w64 on Windows,有两个选项: win32线程和posix线程. 我知道win32线程和pthreads之间的区别,但是我不明白这两个选项之间的区别. 我怀疑如果我 ...
- QT之深入理解QThread
QT之深入理解QThread 理解QThread之前需要了解下QThread类,QThread拥有的资源如下(摘录于QT 5.1 帮助文档): 在以上资源中,本文重点关注槽:s ...
- “QObject调用moveToThread()后 该如何释放”及QThread 的启动关闭
1 QThread *thread = new QThread( ); 2 Task *task = new Task(); 3 task->moveToThread(thread); 4 co ...
- 重点:怎样正确的使用QThread类(注:包括推荐使用QThread线程的新方法QObject::moveToThread)
背景描述: 以前,继承 QThread 重新实现 run() 函数是使用 QThread唯一推荐的使用方法.这是相当直观和易于使用的.但是在工作线程中使用槽机制和Qt事件循环时,一些用户使用错了.Qt ...
- 重点:怎样正确的使用QThread类(很多详细例子的对比,注意:QThread 中所有实现的函数是被创建它的线程来调用的,不是在线程中)good
背景描述: 以前,继承 QThread 重新实现 run() 函数是使用 QThread唯一推荐的使用方法.这是相当直观和易于使用的.但是在工作线程中使用槽机制和Qt事件循环时,一些用户使用错了.Qt ...
随机推荐
- 【Luogu】P1231教辅的组成(拆点+Dinic+当前弧优化)
题目链接 妈耶 我的图建反了两次 准确的说是有两个地方建反了,然后反上加反改了一个小时…… 知道为什么要拆点吗? 假设这是你的图 左边到右边依次是超级源点 练习册 书 答案 ...
- 【Luogu】P2016战略游戏(树形DP)
题目链接 设f[i][j]表示以节点i为根的子树在状态j的情况下的最优解. j有两种情况. j=1:i这个根节点有士兵在站岗. j=0:i这个根节点没有士兵在站岗. 转移方程很好想. f[x][]+= ...
- NOJ——1628Alex’s Game(III)(DFS+回溯)
[1628] Alex’s Game(III) 时间限制: 1000 ms 内存限制: 65535 K 问题描述 Alex likes to play with one and zero as you ...
- [BZOJ1582] [Usaco2009 Hol]Holiday Painting 节日画画(线段树)
传送门 线段树区间修改傻题 #include <cstdio> #include <cstring> #include <iostream> #define N 5 ...
- 【二分+扫描线乱搞】B. Producing Snow
注意二分写法... http://codeforces.com/problemset/problem/923/B #include<cstdio> #include<string.h ...
- angular中关于自定义指令——repeat渲染完成后执行动作
业务中有时需要在异步获取数据并用ng-repeat遍历渲染完页面后执行某个操作,angular本身并没有提供监听ng-repeat渲染完成的指令,所以需要自己动手写.有经验的同学都应该知道,在ng-r ...
- spring boot--常用配置
spring boot 需要引用的依赖项: spring-boot-starter-parent // 所有Spring Boot组件的基础引用 spring-boot-starter-web // ...
- android 活动
一.Activity 声明周期 1 创建 把页面上的个元素加载到内存 onCreate 2 开始 把页面显示到屏幕 onStart 3 恢复 让页面在屏幕活动 onResume 4 暂停 停止页面动作 ...
- HDU - 5584 LCM Walk (数论 GCD)
A frog has just learned some number theory, and can't wait to show his ability to his girlfriend. No ...
- java.nio.ByteBuffer 以及flip,clear及rewind区别
Buffer 类 定义了一个可以线性存放primitive type数据的容器接口.Buffer主要包含了与类型(byte, char…)无关的功能. 值得注意的是Buffer及其子类都不是线程安全的 ...