qt多线程
1 开启线程
QThread类提供了一个平台无关的方式来管理线程。 实际上由于Qt信号槽机制的原因,本人觉得Qt的多线程对新手而言存在很多坑。
Qt中关于线程的类为QThread。只要继承该类,并实现run()方法就可以在主线程中方便的启动新线程,启动函数为QThread.start()。然而,自定义的run()内并没有自动实现Qt的消息循环(当然它也不应该有),因此即便在新线程内连接了信号和槽,新线程也不能处理。如下:
class ElsClient:public QThread
{
Q_OBJECT
public:
explicit ElsClient(QThread *parent = nullptr);
protected:
void run(){
connect(..)//DirectConnection 无效
// do some thing
}
signals:
public slots:
void myFunc();
};
除非在覆写的run()的末尾加上exec()函数。这里有一个问题,run()方法内不能存在死循环,要不然exec()根本不会执行到。此方法的另一个问题在于,例子中的ElsClient一般会在主线程中实例化(假设为elsClient),因此该实例(包括内部的所有变量)都是属于主要线程的 ,此时不能connect elsClient的非指针成员变量,否则出错。以此得出结论,线程的槽不应直接在QThread子类中来实现。
使用Qt线程的还有另一个方式。在QThread类内部的run()方法默认是调用了exec()的,因此可以直接新建QThread的实例,并调用其start()方法运行线程。如下:
QThread workerThread;
Worker *worker = new Worker;//实际工作类
worker->moveToThread(&workerThread);
connect(workerThread, SIGNAL(..), worker, SLOT(..));
workerThread.start();
此时,如果信号发出,SLOT函数将工作在子线程。
感觉QThread不像是被设计成一个线程的基类,倒像是一个线程的管理类。但那个子线程开启/结束的时候会发出started()和finished()信号。用户也可以是isFinished()和isRunning查询线程状态。
exit()/quit()可以用来终止线程。如果要线程强行停止,也可使用terminate().
从Qt4.8起,可以释放运行刚刚结束的线程对象,通过连接finished()信号到QObject::deleteLater().
使用wait()来阻塞调用的线程,直到其他线程执行完毕(或者直到指定的时间过去)。
QThread中还提供了静态的、平台独立的休眠功能:sleep()、msleep()、usleep()允许秒,毫秒和微秒来区分,这些函数在Qt5.0中被设为public。
静态函数currentThreadId()和currentThread()返回标识当前正在执行的线程。前者返回该线程的平台特定的ID,后者返回一个线程指针。
2 结束线程
如果一个线程运行完成,就会结束。可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它。
不恰当的中止往往会引起一些未知错误。比如:当关闭主界面的时候,很有可能次线程正在运行,这时,就会出现如下提示:
QThread: Destroyed while thread is still running
这是因为子线程还在运行,就结束了UI主线程,导致事件循环结束。这个问题在使用线程的过程中经常遇到,尤其是耗时操作。
大多数情况下,当程序退出时,子线程也许会正常退出。但是在极少数的情况下会出现crash!一种方法是使用terminate()函数结束子线程,但是很多情况下某些销毁工作必须得执行,此时terminate()就比较尴尬了。
比较优雅的方式有:
1. 发起线程退出操作,调用quit()或exit()。
2. 等待线程完全停止,删除创建在堆上的对象。
3. 适当的使用wait()(用于等待线程的退出)和合理的算法。
即便如此,有时候当Qt程序被关闭时,也会出现如下错误信息。
QBasicTimer::stop: failed. Possibly trying to stop from a different thread
Stack Overflow上有评论说这个是Qt的一个bug,并不会造成任何问题(事实如何,有待进一步查阅资料)。
相关阅读
银河麒麟(Kylin)完整移植Qt5.9.2, 包含QCharts和QML等
最近项目接触到国产飞腾服务器,搭载的是我们国家自主的银河麒麟操作系统,系统自带Qt5.6,只有widget那套框架,没有QML也没有QCharts,因
背景介绍 在做程序的过程中,我们很可能
刷手想找兼职,到QT刷单房间是不错的选择,但是这里面还有很多细节问题,很多新手刷手并不清楚。也有很多朋友被骗,这些问题今天小编就给
淘宝刷单兼职,可以说能经常在网上见到。像YY刷单、qt刷单平台等。对于qt刷单平台,或许还有不少朋友感到好奇,究竟qt刷单平台在日常是
刚做网赚那个时候,总觉得网赚无所不能。由于少不经事,我觉得只要和网赚沾点边的,那就是我学习的对象。于是,我也经历了很多荒诞不经的