【QT】 QThread部分源码浅析 (3)

由以上源码可知,QThread::quit()QThread::exit(0) 的调用是等效的,都是告诉线程的事件循环,以返回码0(成功)退出。如果线程没有事件,则此函数不执行任何操作,也就是无效的。当线程拥有事件循环并且正处于 事件循环(QThread::exec()) 的状态时,调用 QThread::quit()或者QThread::exit() 线程就会马上停止,否则不会立刻停止线程,直到线程处于事件循环也就是正在执行 QThread::exec() 时,才会停止线程。

如果重复调用 QThread::quit()或者QThread::exit() 会有什么影响吗?
重复调用 QThread::quit()或者QThread::exit() 也不会有什么影响,因为只有拥有事件循环的线程,这两个函数才会生效停止线程的功能。

(2)QThread::terminate()

void QThread::terminate() { Q_D(QThread); QMutexLocker locker(&d->mutex); if (!d->running) return; if (!d->terminationEnabled) { d->terminatePending = true; return; } // Calling ExitThread() in setTerminationEnabled is all we can do on WinRT #ifndef Q_OS_WINRT TerminateThread(d->handle, 0); #endif QThreadPrivate::finish(this, false); //结束线程函数 }

在这个函数定义的最后一个语句,是调用了 QThreadPrivate::finish(this, false); 函数,其函数作用是直接退出线程,无论线程是否开启了事件循环都会生效,会马上终止一个线程,但这个函数存在非常不安定因素,不推荐使用

如果重复调用 QThread::terminate() 会有什么影响吗?
没有影响。我们可以看到函数体里面的第三条语句,它首先会判断线程是否还在运行中,如果不是,会直接退出函数,就不会继续往下执行调用QThreadPrivate::finish(this, false); 函数了。

章节小结

相信看了以上的一些QThread源码,都大概知道了QThread类的本质以及QThread开启到结束的过程。这里我再简单总结下:

(1)QThread的本质:

QThread 是用来管理线程的,它所依附的线程和它管理的线程并不是同一个东西;

QThread 所依附的线程,就是执行 QThread t 或 QThread * t=new QThread 所在的线程;

QThread 管理的线程,就是 run 启动的线程,也就是次线程。

(2)在这里针对Qt4.4版本之后(包括Qt4.4版本)简单汇总一下线程启动到结束的过程:

QThread对象或者QThread派生类对象显式调用QThread类中的外部start()方法;

QThread::start()方法再调用QThreadPrivate::start()方法;

在QThreadPrivate::start()方法内调用了QThread::run()虚函数,对使用者来说到了这里才是真正进入了一个新的线程里面。也就是说定义QThread对象或者QThread派生类对象的时候,还是在原来的线程里面,只有进入run函数才是进入了新的线程;

在QThreadPrivate::start()方法调用QThread::run()虚函数结束后,就会继续调用QThreadPrivate::finish()函数来结束线程,并发出线程结束的信号finished()。

(3)QThread::quit()、QThread::exit()、QThread::terminate():

对线程重复使用这三个停止线程的函数,没有任何影响;

尽量不要使用QThread::terminate()停止线程,此方式是强制退出线程,没有安全保障。

调用QThread::quit()和QThread::exit()一样。

(4)Qt各版本QThread类的变化:

Qt4.4版本之前QThread类是属于抽象类, Qt4.4版本之后(包括4.4版本)不是抽象类。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyzzz.html