Qt 多线程
QThread 的常见特性
run
run()
是线程的入口,就像 main() 对于应用程序的作用。
QThread 中对 run() 的默认实现调用了 exec()
,从而创建一个 QEventLoop 对象,由其处理该线程事件队列(每一个线程都有一个属于自己的事件队列)中的事件。
简单用代码描述如下:
int QThread::exec()
{
//...
QEventLoop eventLoop;
int returnCode = eventLoop.exec();
//...
return returnCode;
}
int QEventLoop::exec(ProcessEventsFlags flags)
{
//...
while (!d->exit) {
while (!posted_event_queue_is_empty) {
process_next_posted_event();
}
}
//...
}
由此可见,exec() 在其内部不断做着循环遍历事件队列的工作,调用 QThread
的 quit()
或 exit()
方法使停止工作,尽量不要使用 terminate()
,该方法过于粗暴,造成资源不能释放,甚至互斥锁还处于加锁状态。
推荐的使用方式:
#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();
}
这是 Qt4.7 及以后版本推荐的工作方式。
其主要特点就是利用 Qt 的事件驱动特性,将需要在次线程中处理的业务放在独立的模块(类)中,由主线程创建完该对象后,将其移交给指定的线程,且可以将多个类似的对象移交给同一个线程。
在这个例子中,信号由主线程的 QTimer 对象发出,之后 Qt 会将关联的事件放到 worker 所属线程的事件队列。
由于队列连接的作用,在不同线程间连接信号和槽是很安全的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Qt GUI 界面假死
下一篇: Covenant 利用分析
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论