zoukankan      html  css  js  c++  java
  • Qt

      QThread Class 详细描述
      QThread 类提供一个平台无关的方法来管理线程。
      一个QThread对象管理一个程序中的控制线程。QThread在run()中开始执行任务。默认地,run()通过调用exec()开始事件循环,并且在线程中运行Qt事件循环。
    你可通过使用QObject::moveToThread()将worker对象移到线程中来使用worker对象。

      

    class Worker : public QObject
      {
          Q_OBJECT
    
      public slots:
          void doWork(const QString &parameter) {
              QString result;
              /* ... here is the expensive or blocking operation ... */
              emit resultReady(result);
          }
    
      signals:
          void resultReady(const QString &result);
      };
    
      class Controller : public QObject
      {
          Q_OBJECT
          QThread workerThread;
      public:
          Controller() {
              Worker *worker = new Worker;
              worker->moveToThread(&workerThread);
              connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
              connect(this, &Controller::operate, worker, &Worker::doWork);
              connect(worker, &Worker::resultReady, this, &Controller::handleResults);
              workerThread.start();
          }
          ~Controller() {
              workerThread.quit();
              workerThread.wait();
          }
      public slots:
          void handleResults(const QString &);
      signals:
          void operate(const QString &);
      };

      

      Worker槽中的代码会在一个单独的线程中执行。然而,你可以自由地将Woker的槽和任何信号相连,不管信号来自哪个对象,在哪个线程中。一个叫做queued connections的机制保证跨不同线程的信号(signals)和槽(slots)的连接(connect)是安全的。
      另外一种将代码运行在独立线程的方法是通过QThread的子类重新实现run()。例如:

     1 class WorkerThread : public QThread
     2   {
     3       Q_OBJECT
     4       void run() Q_DECL_OVERRIDE {
     5           QString result;
     6           /* ... here is the expensive or blocking operation ... */
     7           emit resultReady(result);
     8       }
     9   signals:
    10       void resultReady(const QString &s);
    11   };
    12 
    13   void MyObject::startWorkInAThread()
    14   {
    15       WorkerThread *workerThread = new WorkerThread(this);
    16       connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    17       connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    18       workerThread->start();
    19   }
    View Code

      在上述示例中,线程在run()返回后会退出。线程中没有任何事件循环执行除非你调用exec()。
      需要记住的是QThread实例依存于实例它的旧线程中,不是在调用run()的新线程中。这意味着所有QThread的队列化的槽会在旧线程中执行。因此,开发者想要在新线程中调用槽函数需要使用工作者对象方法(woker-object approach);新的槽函数不应该直接在QThread的子类中实现。
      当定义QThread的子类时,需注意子类的构造函数(constructor)在旧线程中执行,run()在新线程中执行。如果一个成员变量被两个函数访问,则该成员变量是在不同的线程中访问,需要检查访问是否安全(线程同步)。
    线程管理
      QThread在线程started()和finished()时会通过信号(signa)通知你,或者你可以通过isFinished()和isRunning()查询线程的状态。
    你可以通过调用exit()或者quit()停止线程。极端情况下,你可能想通过terminate()强制结束一个线程,但是这样做是危险的,不鼓励如此。
      从Qt4.8开始,当线程刚刚结束时,可以将线程中的对象释放(deallocate),方法是连接finished()信号和QObject::deleteLater()。
    使用wait()阻塞调用线程,直到其他线程执行完成(或者指定的时间已过)。
      QThread也提供静态的、平台无关的睡眠函数(sleep):sleep(),msleep(),usleep(),分别的精度是秒,毫秒,微秒。
      Note:wait()和sleep()函数一般不需要,因为Qt是一个事件驱动框架。考虑监听finished()信号替换wait()函数,用QTimer替换sleep()函数。
      静态函数currentThreadId()和currentThread()返回当前执行线程的标识。前者返回平台为线程指定的ID,后者返回一个QThread指针。
      在启动线程之前调用setObjectName(),可选择线程名字(类似于linux命令 ps -L)。如果不调用setObjectName(),给定的线程名字是线程对象运行时类名字。注意在Windows系统release builds时,该函数暂不可用。

  • 相关阅读:
    生产者-消费者模型-线程安全队列Queue
    多线程简单案例
    cloudstack 用admin 账号创建虚拟机只是提示insufficient resource
    什么是工厂函数?Python 中工厂函数怎么理解?(转)
    rsync + mysql + gzip + --single-transaction
    Python中获取异常(try Exception)信息
    ansible copy 模块 changed false 没有变化
    _mysql.c:29:20: error: Python.h: No such file or directory
    常用网址
    Android 中常见控件的介绍和使用
  • 原文地址:https://www.cnblogs.com/Pan-Z/p/6223186.html
Copyright © 2011-2022 走看看