前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >翻译 | 您没有做错(线程)

翻译 | 您没有做错(线程)

作者头像
Qt君
发布2019-10-23 19:17:09
5920
发布2019-10-23 19:17:09
举报
文章被收录于专栏:跟Qt君学编程跟Qt君学编程

本文翻译自: https://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html 原作者: Olivier Goffart 发布时间:2013年1月22日

  这篇文章是关于QThread的使用的。这是对我当时的同事Brad三年前的博客帖子的回答:“您做错了”。

  Brad在他的博客文章中解释说,他看到许多用户通过对QThread进行子类化,在该子类中添加一些槽并在构造函数中执行以下操作来滥用QThread:

代码语言:javascript
复制
 moveToThread(this);

  他们把线程移动到自己类内。正如Brad所提到的,这是错误的:QThread应该是管理线程的接口。因此,应该在创建线程中使用它。

  这样,就无法在该线程中运行QThread对象中的槽,并且在QThread的子类中具有槽是一种不好的做法。

  但是,Brad继续并完全不鼓励使用QThread的任何子类。他声称这违反了正确的面向对象设计。这是我不同意的地方。放入代码run()是扩展QThread的一种有效的面向对象方法:QThread表示一个仅启动事件循环的线程,子类表示一个被扩展以执行其工作的线程run()

  Brad上任后,该社区的一些成员就反对对QThread进行子类化进行了讨伐。问题在于,有很多完全合法的原因可以继承QThread。

  在Qt 5.0和Qt 4.8.4中,更改了QThread的文档,因此示例代码不涉及子类。查看Qt 4.8 QThread文档的第一个代码示例(更新的文档已经修复)。它具有许多样板行,仅用于在线程中运行一些代码。而且甚至存在泄漏:QThread永远不会退出并被销毁。

  我在IRC上被问到一个用户的问题,该用户遵循该示例,以便在线程中运行一些简单的代码。他很难弄清楚如何正确销毁线程。这就是促使我撰写此博客条目的原因。

  如果允许子类化QThread,那么您将获得:

代码语言:javascript
复制
class WorkerThread : public QThread {
    void run() {
        // ...
    }
};

void MyObject::startWorkInAThread()
{
    WorkerThread *workerThread = new WorkerThread;
    connect(workerThread, SIGNAL(finished()),
            workerThread, SLOT(deleteLater()));
    workerThread->start();
}

  此代码不再泄漏,并且更加简单,并且不会创建无用的对象,因此开销较小。

  Qt线程示例threadedfortuneserver是使用此模式运行阻塞操作的示例,并且比使用worker对象的等效示例要简单得多。

  我已经向文档提交了补丁, 以免再次阻止对QThread的子类化。

经验法则


什么时候子类化,什么时候不子类化?

  • 如果您确实不需要线程中的事件循环,则应该子类化。
  • 如果需要事件循环并处理线程中的信号和槽,则可能不需要子类化。

改用QtConcurrent呢?

  QThread的级别很低,您最好使用更高级别的API,例如QtConcurrent。

  现在,QtConcurrent有其自身的一系列问题:它与单个线程池绑定,因此如果要运行阻塞操作,它不是一个好的解决方案。在其实现中还存在一些问题,这些问题会带来一些性能开销。所有这些都是可以修复的。也许甚至Qt 5.1也会有所改进。

  一个很好的选择也是C ++ 11与标准库 std::thread 和std::async它们现在在一个线程中运行的代码的标准方式。好消息是它仍然可以在Qt上正常工作:所有其他Qt线程原语都可以与本机线程一起使用。(如果需要,Qt将自动创建一个QThread来创建)


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Qt君 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 经验法则
    • 什么时候子类化,什么时候不子类化?
      • 改用QtConcurrent呢?
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档