使用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 ...
随机推荐
- BZOJ 4810 [Ynoi2017]由乃的玉米田 ——Bitset 莫队算法
加法和减法的操作都能想到Bitset. 然后发现乘法比较难办,反正复杂度已经是$O(n\log{n})$了 枚举因数也不能更差了,直接枚举就好了. #include <map> #incl ...
- 【单调队列优化dp】uestc 594 我要长高
http://acm.uestc.edu.cn/#/problem/show/594 [AC] #include<bits/stdc++.h> using namespace std; t ...
- bzoj1584 [Usaco2009 Mar]Cleaning Up 打扫卫生 动态规划+思维
Description 有N头奶牛,每头那牛都有一个标号Pi,1 <= Pi <= M <= N <= 40000.现在Farmer John要把这些奶牛分成若干段,定义每段的 ...
- json-lib maven依赖出错的问题
项目中要用到json-lib,mvnrepository.com查找它的dependency时结果如下: xml 代码 <dependency> <groupId>net.sf ...
- Windows下使用Nexus搭建Maven私服(使用)
注意: 1.从3.0版本的Nexus开始,已经不再缓存https://repo1.maven.org/maven2/的包,所以当安装好之后,在界面上不会有任何的包可以搜索到,但是功能是一切正常的,只有 ...
- iOS开发 检测版本更新
iOS开发 检测版本更新的实现 苹果给了我们一个接口,能根据应用id请求一些关于应用的信息.我们可以根据返回的信息,来判断版本是否和应用的版本一致,如果不一致,那么就出现新的版本了.这时,就需要向用户 ...
- 全能无线渗透测试工具,一个LAZY就搞定了
近来一直在研究无线安全方面的东西,特别是在无线渗透测试这块,每次渗透测试时总要来回不停的切换操作和挑选利器,很是麻烦.就想看看是否可以有一款功能全面的集合型工具. 正所谓功夫不负有心人,还真有这么一个 ...
- 基于MNIST数据的卷积神经网络CNN
基于tensorflow使用CNN识别MNIST 参数数量:第一个卷积层5x5x1x32=800个参数,第二个卷积层5x5x32x64=51200个参数,第三个全连接层7x7x64x1024=3211 ...
- (转) SYSTEM_HANDLE_INFORMATION中ObjectTypeIndex的定义
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO{ USHORT UniqueProcessId; USHORT CreatorBackTraceIndex ...
- 【C#】高级语言特有的单例模式
public class Singleton { private Singleton () { } // 变量标记为 readonly.第一次引用类的成员或创建实例时,仅仅实例化一次instance对 ...