必威体育Betway必威体育官网
当前位置:首页 > IT技术

Qt多线程

时间:2019-08-10 15:42:11来源:IT技术作者:seo实验室小编阅读:83次「手机版」
 

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,因

BackgroundWorker 实现多线程操作

  背景介绍                                         在做程序的过程中,我们很可能

qt淘宝刷单技巧分析,新刷手必看

刷手想找兼职,到QT刷单房间是不错的选择,但是这里面还有很多细节问题,很多新手刷手并不清楚。也有很多朋友被骗,这些问题今天小编就给

怎样进入qt刷单平台

淘宝刷单兼职,可以说能经常在网上见到。像YY刷单、qt刷单平台等。对于qt刷单平台,或许还有不少朋友感到好奇,究竟qt刷单平台在日常是

qt语音网赚骗局,200元血淋淋的教训让我不堪回首

刚做网赚那个时候,总觉得网赚无所不能。由于少不经事,我觉得只要和网赚沾点边的,那就是我学习的对象。于是,我也经历了很多荒诞不经的

分享到:

栏目导航

推荐阅读

热门阅读