您的位置:首页 > 编程语言 > Qt开发

QThread 的使用方法 注意事项

2015-10-27 15:05 435 查看
起源

昨天不小心看到Qt开发人员( Bradley T. Hughes)Blog中的一片文章 you are-doing-it-wrong 。 结果看得头昏脑胀:好歹也自学了近1年的Qt,也一直很小心、很认真地阅读Qt和manual和例子等资料,却被突然告知,QThread的正确使用方法是一种自己从没见过,而且Qt
manual、example、书籍中都没有提到过的一种方法。到底怎么了...

莫非manual、exmaple以及资料中的介绍都是错的??

认真看看其他的人的评论,总算理清了一点头绪。所有事情源于 QThread 的事件循环!

QThread 的两种使用方法

1. 不使用事件循环。这是官方的 Manual 、example 以及相关书籍中都介绍的一种的方法。

a. 子类化 QThread

b. 重载 run 函数,run函数内有一个 while 或 for 的死循环

c. 设置一个标记为来控制死循环的退出。

如果使用这一方法,QThread::quit()没有效果。因为这个线程根本就不需要事件循环。这种情况想退出,直接使用QT很不推荐的terminate().

最常用的就是这种方法。

2. 使用事件循环。(博客 you are-doing-it-wrong 批驳的就是这种情况下的 一种用法。)

a. 子类化 QThread,

b. 重载 run 使其调用 QThread::exec()

c. 并为该类定义信号和槽,这样一来,由于槽函数并不会在新开的 thread 运行,很多人为了解决这个问题在构造函数中调用
moveToThread(this);

而争论和不解正是这样的一条语句造成的。
Bradley T. Hughes 给出说明是: QThread 应该被看做是操作系统线程的接口或控制点,而不应该包含需要在新线程中运行的代码。需要运行的代码应该放到一个QObject的子类中,然后将该子类的对象moveToThread到新线程中。

另外:

在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。

而从Qt4.4开始,qthreads-no-longer-abstract
,run 默认调用 QThread::exec() 。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject 就够了,这正是被 Bradley T. Hughes推荐的方法。

终于看懂了,但

不管怎么说,都应该是 QThread 当初的设计导致的这种问题,而所有文档和例子中都没有提到该如何使用Qthread 进一步加剧了对QThread的这种误用。

另注:1.QThread对象从建立起就是活跃的,所以大牛Bradley T. Hughes把QObject对象移动到QThread中,对QObject的操作是完全合理合法合逻辑的。

2.既然使用了多线程,就必须考虑互斥问题,QThread的所有slot函数都是可多重入和不安全的(具体参见QT的可重入和线程安全)。而且在此之外,除了GUI类对象必须在主进程(不可重入,从而保证了线程安全),互斥锁一类的类可重入和线程安全外。所以的QObject对象都不是线程安全的,换句话说,在主线程内为单线程设计的QObject子类对象,如果没有对其slot函数做互斥处理,就会出现因signal调用而反复重入某个slot函数的情况,反而成了多线程。(C++对象,由于是顺序调用,所以在单线程下不会出现这个问题)。这时需要依据情况考虑互斥锁。

3.使用大牛Bradley
T. Hughesr的方法把QObject对象移动到QThread中,要使用signal+slot的方式来调用函数,这样的话,通过QT消息机制,QObject被调用的函数是在线程内执行。如果直接(QObject对象).abc()的话,这个成员函数是在主进程内执行,可能会出现"QObject::killTimer: timers cannot be stopped from another thread"的运行错误。

相关链接:
http://labs.qt.nokia.com/blogs/2010/06/17/youre-doing-it-wrong/ http://labs.qt.nokia.com/blogs/2006/12/04/threading-without-the-headache/ http://labs.qt.nokia.com/blogs/2007/07/05/qthreads-no-longer-abstract/ http://gitorious.org/qthreadhowto/qthreadhowto/trees/master http://blog.exys.org/entries/2010/QThread_affinity.html http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: