QT5(16)多线程 Thread
推荐一博客
Qt提供两种多线程方式。一种继承QThread类;另一种采用movetothread。在Qt中采用事件循环(QEvenLoop)处理时间。
一、继承QThread
Qt线程中默认run函数调用exec()执行事件循环。但是如果继承的run函数没有启动事件循环,run函数就不会阻塞。如果我们需要启动线程内的事件循环,就需要手动执行exec()。
注意继承自QThread的类在子线程中只有run()函数部分能够在子线程中运行。其他部分还是在主线程中运行。
#include <QtCore>
class Thread : public QThread { private: void run() { qDebug()<<"From worker thread: "<<currentThreadId(); } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug()<<"From main thread: "<<QThread::currentThreadId(); Thread t; QObject::connect(&t, SIGNAL(finished()), &a, SLOT(quit())); t.start(); return a.exec(); }
如果run函数没有启用事件循环,那么一般情况下我们通过设置flag来结束进程。启用事件循环exec()后,线程不断做着循环遍历事件队列的工作,调用QThread的quit()或exit()方法使停止线程,尽量不要使用terminate(),会造成资源不能释放,甚至互斥锁还处于加锁状态。其中quit与terminate是槽,可以直接用信号连接关闭线程。线程被终止时,所有等待该线程Finished的线程都将被唤醒。
#include "QThread"
#include "QMutexLocker"
#include "QMutex"
class Thread:public QThread
{
Q_OBJECT
public:
Thread();
void stop();
private:
bool m_stopFlag;
QMutex mutex;
protected:
void run();
};
Thread::Thread()
{
m_stopFlag = false;
}
void Thread::stop()
{
QMutexLocker locker(&mutex);
m_stopFlag = true;
}
void Thread::run()
{
while(1){
{
QMutexLocker locker(&mutex);
if(m_stopFlag)
break;
}
qDebug()<<"This is in thread["<<currentThreadId()<<"]."<<(int)currentThread();
sleep(2);
}
m_stopFlag = false;
}
二、movetothread
目前的推荐做法:子类继承QObject,然后使用movetothread将对象交给子线程,当信号发出后,Qt会将SLOT函数提交给子线程,放在子线程中执行。类的SLOT的函数都能够在线程中执行。
include <QtCore>
class Worker : public QObject { Q_OBJECT private slots: void onTimeout() { qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId(); } }; #include "main.moc" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); qDebug()<<"From main thread: "<<QThread::currentThreadId(); QThread t; QTimer timer; Worker worker; QObject::connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout())); timer.start(1000); worker.moveToThread(&t); t.start(); return a.exec(); }
三、connect最后一个参数
参数 | 解释 |
---|---|
Qt::AutoConnection | 默认连接方式,如果信号与槽在同一线程,等同于直接连接;在不同线程,等同于队列连接。 |
Qt::DirectConnection | 无论槽函数所属对象在哪个线程,槽函数都在信号的线程内执行,使用该连接,槽将会不在线程执行。 |
Qt::QueuedConnection | 槽函数在对象的当前线程中按照队列顺序执行。如果线程停止,就会等待下一次启动线程时再按队列顺序执行。 |
Qt:: BlockingQueuedConnection | 只有槽函数在线程执行完才会返回,否则发送线程也会等待。 |
Qt::UniqueConnection | 与AutoConnect相同,只是不能重复连接相同的信号和槽。 |
Qt::AutoCompatConnection | 兼容老版本 |
附上练手的百度私链破解程序(已失效,目前多次密码出错,链接404错误。)
还没有评论,来说两句吧...