QThread 认知
Posted huanyinglvtuan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QThread 认知相关的知识,希望对你有一定的参考价值。
QThread 认知
线程启动
void start(Priority priority = InheritPriority)
调用后会执行run()函数,但在run()函数执行前会发射信号started(),操作系统将根据优先级参数调度线程。如果线程已经在运行,那么这个函数什么也不做。优先级参数的效果取决于操作系统的调度策略。特别是那些不支持线程优先级的系统优先级将会被忽略(例如在Linux中,更多细节请参考http://linux.die.net/man/2/sched_setscheduler)
下面来看下优先级中的各个枚举值:
Constant | Value | Description |
---|---|---|
QThread::IdlePriority | 0 | 没有其它线程运行时才调度. |
QThread::LowestPriority | 1 | 比LowPriority调度频率低. |
QThread::LowPriority | 2 | 比NormalPriority调度频率低. |
QThread::NormalPriority | 3 | 操作系统默认的默认优先级. |
QThread::HighPriority | 4 | 比NormalPriority调度频繁. |
QThread::HighestPriority | 5 | 比HighPriority调度频繁. |
QThread::TimeCriticalPriority | 6 | 尽可能频繁的调度. |
QThread::InheritPriority | 7 | 使用和创建线程同样的优先级. 这是默认值. |
案例
#ifndef ASENDTUNNEL_H
#define ASENDTUNNEL_H
#include <QObject>
#include <QTimer>
#include <QThread>
class AThreadTestObj : public QObject
{
Q_OBJECT
public:
explicit AThreadTestObj(QObject *parent = 0);
void printInfo();
signals:
public slots:
void sltInit();
void sltDeinit();
void sltTimeOut();
private:
QTimer *m_ptimer;
QThread m_thread;
};
#endif // ASENDTUNNEL_H
#include "asendtunnel.h"
#include <QDebug>
AThreadTestObj::AThreadTestObj(QObject *parent) : QObject(parent)
{
moveToThread(&m_thread);
connect(&m_thread, &QThread::started, this, &AThreadTestObj::sltInit);
connect(&m_thread, &QThread::finished, this, &AThreadTestObj::sltDeinit);
m_thread.start(QThread::TimeCriticalPriority);
}
void AThreadTestObj::printInfo()
{
qDebug() << "printInfo:" << QThread::currentThreadId();
}
void AThreadTestObj::sltInit()
{
m_ptimer = new QTimer();
connect(m_ptimer, &QTimer::timeout, this, &AThreadTestObj::sltTimeOut);
m_ptimer->start(5000);
qDebug() << "sltInit:" << QThread::currentThreadId();
}
void AThreadTestObj::sltDeinit()
{
delete m_ptimer;
}
void AThreadTestObj::sltTimeOut()
{
qDebug() << "sltTimeOut:" << QThread::currentThreadId();
}
#include <QCoreApplication>
#include "asendtunnel.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
AThreadTestObj m_sendTunnel;
m_sendTunnel.printInfo();
return a.exec();
}
结果:
printInfo: 0x6f34
sltInit: 0x68b8
sltTimeOut: 0x68b8
sltTimeOut: 0x68b8
总结:外面调用接口执行的是主线程,子线程执行的内容通过定时器,因为定时器是在子线程创建的,另外从执行的顺序来看,最好的主线程在创建对象后最后有个等待再去执行其他接口
案例:加了等待初始化接口
#ifndef ASENDTUNNEL_H
#define ASENDTUNNEL_H
#include <QObject>
#include <QTimer>
#include <QThread>
#include <QAtomicInt>
class AThreadTestObj : public QObject
{
Q_OBJECT
public:
explicit AThreadTestObj(QObject *parent = 0);
~AThreadTestObj();
bool waitForStarted();
void waitForStoped();
void printInfo();
signals:
public slots:
void sltInit();
void sltDeinit();
void sltTimeOut();
private:
QTimer *m_ptimer;
QThread m_thread;
QAtomicInt m_iInitSuccess{0};
};
#endif // ASENDTUNNEL_H
#include "asendtunnel.h"
#include <QDebug>
AThreadTestObj::AThreadTestObj(QObject *parent) : QObject(parent),m_ptimer(nullptr)
{
moveToThread(&m_thread);
connect(&m_thread, &QThread::started, this, &AThreadTestObj::sltInit);
connect(&m_thread, &QThread::finished, this, &AThreadTestObj::sltDeinit);
if(!waitForStarted())
throw std::runtime_error("waitForStarted error");
}
AThreadTestObj::~AThreadTestObj()
{
waitForStoped();
}
bool AThreadTestObj::waitForStarted()
{
m_thread.start(QThread::TimeCriticalPriority);
int i =0;
while(m_iInitSuccess.load() !=1)
{
QThread::msleep(100);
if(m_iInitSuccess.load() == -1)
{
waitForStoped();
qDebug()<<"AThreadTestObj start failed";
return false;
}
if(300 == ++i)
{
waitForStoped();
qDebug()<<"AThreadTestObj start failed due to timeout";
return false;
}
}
qDebug()<<"AThreadTestObj start Succeed wait times:"<<i;
return true;
}
void AThreadTestObj::waitForStoped()
{
m_thread.quit();
m_thread.requestInterruption();
m_thread.wait();
qDebug() << "AThreadTestObj::waitForStoped";
}
void AThreadTestObj::printInfo()
{
qDebug() << "printInfo:" << QThread::currentThreadId();
}
void AThreadTestObj::sltInit()
{
m_ptimer = new QTimer();
if(m_ptimer == nullptr)
{
m_iInitSuccess.store(-1);
return;
}
connect(m_ptimer, &QTimer::timeout, this, &AThreadTestObj::sltTimeOut);
m_ptimer->start(5000);
qDebug() << "sltInit:" << QThread::currentThreadId();
m_iInitSuccess.store(1);
}
void AThreadTestObj::sltDeinit()
{
delete m_ptimer;
}
void AThreadTestObj::sltTimeOut()
{
qDebug() << "sltTimeOut:" << QThread::currentThreadId();
}
#include <QCoreApplication>
#include <QDebug>
#include "asendtunnel.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
try
{
AThreadTestObj m_sendTunnel;
m_sendTunnel.printInfo();
return a.exec();
}
catch(std::runtime_error &e)
{
qDebug() << e.what();
}
catch(...)
{
qDebug() << "error";
}
return a.exec();
}
sltInit: 0x73f0
AThreadTestObj start Succeed wait times: 1
printInfo: 0x6fe0
sltTimeOut: 0x73f0
sltTimeOut: 0x73f0
以上是关于QThread 认知的主要内容,如果未能解决你的问题,请参考以下文章