使用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 ...
随机推荐
- 算法复习——迭代加深搜索(骑士精神bzoj1085)
题目: Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相 ...
- tarkjan求无向图割点模板
#include<bits/stdc++.h> using namespace std; typedef long long ll; int n,m; ; ; struct node { ...
- docker 给容器配置ip(和主机一个网段)
docker 给容器配置ip(和主机一个网段).详情参考:http://www.xiaomastack.com/2015/02/06/docker-static-ip/ #/bin/bash ] || ...
- 二分图最小覆盖的Konig定理及其证明,最小的覆盖证明
[转http://www.cppblog.com/abilitytao/archive/2009/09/02/95147.html -> http://yejingx.ycool.com/p ...
- indexedDB 增删改查
/** * 打开数据库 */ export function openDB() { return new Promise((resolve, reject) => { let indexedDB ...
- Linux系统下rz/sz工具的安装
(1)编译安装 root 账号登陆后,依次执行以下命令: wget http://www.ohse.de/uwe/releases/lrzsz-0.12.20.tar.gz tar zxvf lrzs ...
- intellij idea 和 myeclipse 转换
原文出处:http://chinaxxren.iteye.com/blog/893970 当只用 intellij idea 建立 工程 1.首先是new project--->create p ...
- android图片上传
package com.example.center; import java.io.ByteArrayOutputStream;import java.io.InputStream; import ...
- Jetson TK1 一:调整屏幕分辨率
先点击分辨率调整的那个对话框,就是1024×768之类的那个,选定一个分辨率,我选的是1366x768(16:9)的那个,然后连续按7下tab按键,然后回车,然后再点击弹出的选项右边一个就能保存了.
- 使用nginx转发不了静态文件
从django runserver的请求来看,都收不到静态文件请求, 查看firefox的web console请求,发现都是403 然后发现nginx不在当前用户组,并且当前用户的项目的读写权限是7 ...