使用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 ...
随机推荐
- tomcat设置去项目路径
1. 新建一个目录专门用于存放工程, 如: G:\apache-tomcat-6.0.20\project 2. 将工程存放到以上目录下:即:G:\apache-tomcat-6.0.20\proje ...
- msp430项目编程35
msp430中项目---nand接口编程35 1.电路工作原理 2.代码(显示部分) 3.代码(功能实现) 4.项目总结
- php生成压缩包
$filename = "./" . date ( 'YmdH' ) . ".zip"; // 最终生成的文件名(含路径) // 生成文件 $zip = new ...
- rman备份OBSOLETE和EXPIRED参数来历及区别
http://blog.itpub.net/30496894/viewspace-2096221/
- PAT (Advanced Level) 1087. All Roads Lead to Rome (30)
暴力DFS. #include<cstdio> #include<cstring> #include<cmath> #include<vector> # ...
- 一个iOS开发者的Flutter“历险记”
1. 官方简介 Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. 官方介绍: 快速开发: 毫秒级的热重载,修改后,您的应用界面会立即更新.使用丰富的.完 ...
- pandaboard串口通信调试
1.在PC上的pyserial程序,到pandaboard后报错,读取和写入会报错 2.使用的是pandaboard的ttyO2串口 3.ls -l /dev/ttyO2,发现是tty,而不是dial ...
- Java网络编程之InetAddress和URL
在Java中提供了专门的网络开发程序包---java.net,java的网络编程提供了两种通信协议:TCP(传输控制协议)和UDP(数据报协议). 一.IP(Internet Protocol) 与I ...
- 使用UltraISO刻录自己的音乐CD步骤
1.文件->新建->音乐光盘映像. 2.在左下方,“本地目录”中,找到音乐所在目录,右下方会出现mp3等音乐文件. 3.在右下方,点击音乐文件,右键选“添加”.音乐文件会出现在右上方窗口里 ...
- hdoj-3371-Connect the Cities【最小生成树】
Connect the Cities Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...