QThread的细节描述(Detailed Description)翻译

The QThread class provides a platform-independent way to manage threads.

QThread类提供了跨平台的线程管理方式。

A QThread object manages one thread of control within the program. QThreads begin executing inrun(). By default,run() starts the event loop by callingexec() and runs a Qt event loop inside the thread.

一个QThread对象在程序内管理一个线程的控制。QThread启动于run()的执行。默认下,通过调用exec(),run()启动事件循环(event loop),并在线程中运行一个Qt事件循环。

You can use worker objects by moving them to the thread usingQObject::moveToThread().

可以通过使用QObject::moveToThread()将工作者对象(worker objects)移动到某个线程。

  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 &);
  };

The code inside the Worker's slot would then execute in a separate thread. However, you are free to connect the Worker's slots to any signal, from any object, in any thread. It is safe to connect signals and slots across different threads, thanks to a mechanism called queued connections.

在Worker中的槽函数将会在另一个线程中执行。在任意线程中的任意对象的任意信号都可以和Worker的槽函数连接。由于队列连接(queued connections)机制,跨线程连接信号和槽函数是安全的。

Another way to make code run in a separate thread, is to subclassQThread and reimplementrun(). For example:

让代码运行在其他线程的另一种方法是继承QThread并重新实现run()。例如:

  class WorkerThread : public QThread
  {
      Q_OBJECT
      void run() override {
          QString result;
          /* ... here is the expensive or blocking operation ... */
          emit resultReady(result);
      }
  signals:
      void resultReady(const QString &s);
  };

  void MyObject::startWorkInAThread()
  {
      WorkerThread *workerThread = new WorkerThread(this);
      connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
      connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
      workerThread->start();
  }

In that example, the thread will exit after the run function has returned. There will not be any event loop running in the thread unless you callexec().

在例子中,线程将会在run函数返回后退出(exit)。除非调用exec(),线程中不回运行任何事件循环(event loop)。

It is important to remember that aQThread instancelives in the old thread that instantiated it, not in the new thread that callsrun(). This means that all ofQThread's queued slots will execute in the old thread. Thus, a developer who wishes to invoke slots in the new thread must use the worker-object approach; new slots should not be implemented directly into a subclassedQThread.

有一点非常重要,一个QThread实例生存在实例化它的线程中,而并非生存在其调用run()所在的新线程中。这意味着所有QThread的槽函数都只能在原来的线程中执行。因此,开发者希望在新线程执行槽函数,必须使用工作者对象的方法;新的槽函数不应在QThread的子类中实例化。

When subclassingQThread, keep in mind that the constructor executes in the old thread whilerun() executes in the new thread. If a member variable is accessed from both functions, then the variable is accessed from two different threads. Check that it is safe to do so.

当使用QThread的子类时,谨记,构造器在原来的线程中运行,run()在新线程中运行。如果这两个函数都使用一个成员变量,则这个成员变量被两个线程使用,要检查这种做法的安全性。

Note:Care must be taken when interacting with objects across different threads. SeeSynchronizing Threads for details.

注意:对象的跨线程操作时必须小心。更多细节参见同步线程(Synchronzing Threads)的内容。

Managing Threads

管理线程

QThread will notifiy you via a signal when the thread isstarted() andfinished(), or you can useisFinished() andisRunning() to query the state of the thread.

QThread在线程开始和结束时,均会通过信号产生提示。也可以使用isFinshed()和isRunning()查询线程状态。

You can stop the thread by callingexit() orquit(). In extreme cases, you may want to forciblyterminate() an executing thread. However, doing so is dangerous and discouraged. Please read the documentation forterminate() andsetTerminationEnabled() for detailed information.

停止线程可以调用exit()或quit()。在极端情况下,terminate()可以强制终结一个运行中的线程。然而,这么做是危险的,并不鼓励。更多相关细节,请阅读terminate()和setTerminationEnabled()的文档。

From Qt 4.8 onwards, it is possible to deallocate objects that live in a thread that has just ended, by connecting thefinished() signal toQObject::deleteLater().

从Qt 4.8以后,可以用过将finished()信号和QObject::deleteLater()连接,将生存在结束的(ended)线程中的对象释放掉(deallocate)。

Use wait() to block the calling thread, until the other thread has finished execution (or until a specified time has passed).

使用wait()阻塞调用线程,直到其他线程运行结束或直到经过了指定的时间。

QThread also provides static, platform independent sleep functions:sleep(),msleep(), andusleep() allow full second, millisecond, and microsecond resolution respectively. These functions were made public in Qt 5.0.

QThread也提供了静态的跨平台的sleep函数:sleep(),msleep(),和usleep(),分别精度为秒、毫秒和微秒。这些函数在Qt 5.0中是公用的。

Note:wait() and thesleep() functions should be unnecessary in general, since Qt is an event-driven framework. Instead ofwait(), consider listening for thefinished() signal. Instead of thesleep() functions, consider usingQTimer.

注意:wait()和sleep()函数一般是不必要的,因为Qt是事件驱动的框架。代替wait(),考虑使用对finished()信号的监听;代替sleep(),考虑使用QTimer。

The static functionscurrentThreadId() andcurrentThread() return identifiers for the currently executing thread. The former returns a platform specific ID for the thread; the latter returns aQThread pointer.

静态函数 currentThreadId() 和 currentThread() 返回现在运行的线程的标识符。前者的返回值为有平台差异的线程ID;后者返回QThread指针。

To choose the name that your thread will be given (as identified by the commandps -L on Linux, for example), you can callsetObjectName() before starting the thread. If you don't callsetObjectName(), the name given to your thread will be the class name of the runtime type of your thread object (for example,"RenderThread" in the case of theMandelbrot Example, as that is the name of theQThread subclass). Note that this is currently not available with release builds on Windows.

可以给线程命名(例如,在Linux中使用命令ps -L识别),可以在线程开始前调用setObjectName()。如果没有调用setObjectName(),线程名将会是线程对象的运行类型的类名(例如,……)。注意,在Windows的release编译下不可用。

See alsoThread Support in Qt,QThreadStorage,Synchronizing Threads,Mandelbrot Example,Semaphores Example, andWait Conditions Example.






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值