Qt中的线程化

3
我在互联网上看到说子类化(即从QThread派生一个类),然后重写run函数来执行所需任务不是使用QThread的正确方式。但我在一些书籍和Qt文档中读到要使用子类化的方式?
你能告诉我为什么不应该使用子类化的方式吗?对我来说,子类化QThread是使用线程的简单方法(因为我是初学者)。
谢谢。

1
可能是Qt编程和需要很长时间的计算的重复问题。 - Tamás Szelei
@Nawaz,这可能来自我最近一个问题的答案:http://stackoverflow.com/questions/9638226/signal-prior-qthread-event-loop-start-is-lost - edA-qa mort-ora-y
3个回答

2
请看这篇关于QThread的好文章:Christoph Eckert的《The great QThread Mess》,它引导我以现在这种方式使用QThread:Bradley T. Hughes的《Threading without the headache》
总之,在我看来,使用QThread最简单的方法是创建一个QObject子类,使用信号/槽,并使用moveToThread使对象在不同的线程中具有不同的事件循环。
不幸的是,如果您绝对需要一个"while(true)"类型的线程,这种方法无法奏效,但在Qt中通常可以避免这种情况。

请问您能否告诉我这是什么意思!对于初学者来说,这很令人困惑。 “QThread中的所有函数都是为了从创建线程而不是QThread启动的线程中调用而编写和设计的。” - Umer Farooq
创建线程是“拥有”QThread对象的线程。QThread本身不是线程,它管理着驻留在不同事件循环中的线程,这解释了“QThread启动的线程”。 - Chris Browet

1

QThread被设计并且旨在作为操作系统线程的接口或者控制点而使用,而不是放置想要在线程中运行的代码的地方。我们面向对象的程序员使用子类是因为我们想要扩展或者专门化基类的功能。我能够想到唯一合理的子类化QThread的原因是添加QThread没有的功能,例如提供一个指针来用作线程栈的内存,或者可能添加实时接口/支持。下载文件的代码,或者查询数据库的代码,或者进行任何其他处理的代码都不应该被添加到QThread的子类中;它应该被封装在自己的对象中。

更多细节请查看此处...

http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/


@ shobi 先生,创建线程是什么意思?这个语句是什么意思?没关系 :) “QThread中的所有函数都是为了从创建线程而不是QThread启动的线程调用而编写和设计的。” - Umer Farooq
@UmerFarooq 如果你想创建一个线程,那么你只需要创建 QThread 类的对象即可,不需要有一个继承 QThread 类的类。 - shofee
是的,谢谢您先生,还有一点点困惑。正如Koying所提到的:“它管理着驻留在不同事件循环中的线程”。这是什么意思? - Umer Farooq
1
这意味着您的QThread就像一个处理线程的包装器。现在,当您实例化一个QThread对象时,新线程被创建,这意味着创建QThread对象的方法在主线程上,而调用QThread :: start()的方法在新创建的线程上。 - shofee
Qt非常古老,但本文相当新。QThread的接口明显意在派生。一些功能,例如没有消息循环,只能通过从QThread派生来实现。 - edA-qa mort-ora-y

1

QThread文档明确指出,子类化是正确的做法:

要创建自己的线程,请子类化QThread并重新实现run()

然而,这有点令人困惑,因为(正如shobi在另一个答案中指出的那样),这是一种丑陋的设计,存在另一种替代方案。


Shobi的回答忽略了API目前并不完全适用于另一种解决方案。与像boost thread这样好的API不同,您不能轻松地提供任何函数来在线程中执行--信号/槽方法更加复杂,并假定您需要一个事件循环,这可能并不正确。 - edA-qa mort-ora-y

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接