<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Qt中當(dāng)程序結(jié)束時線程的退出


      在Qt程序結(jié)束時應(yīng)該如何退出正在運行的任務(wù)子線程?

      因個人經(jīng)驗和能力有限,本文僅供參考,有錯誤或者考慮不完善的地方請各位批評指正。

      一、正常情況下如何創(chuàng)建和退出線程

      1.繼承QThread,重寫run()函數(shù)

      點擊折疊或展開代碼
      // 類的定義
      class WorkThread1 : public QThread
      {
      public:
          explicit WorkThread1(QObject *parent = 0);
      signals:
          // 線程運行完成
          void workDone();
      public slots:
          // 停止線程
          void stopThread();
      protected:
          // 重寫run()函數(shù)
          virtual void run() override;
      private:
          // 是否停止運行
          bool isStop = false;
      };
      
      WorkThread1::WorkThread1(QObject *parent) : QThread(parent)
      {
      
      }
      void WorkThread1::run()
      {
          for (int i = 0; i < 10; ++i) {
              if (isStop) {
                  return ;
              }
              // 執(zhí)行耗時操作
              // TODO
          }
      }
      void WorkThread1::stopThread()
      {
          isStop = true;
      }
      
      // 外部調(diào)用
      // 兩個按鈕,分別開啟和停止線程
      QPushButton *start = new QPushButton(this);
      QPushButton *stop = new QPushButton(this);
      WorkThread1 *thread1 = new WorkThread1(this);
      connect(start, &QPushButton::clicked, [=](){
          thread1->start();
      });
      connect(stop, &QPushButton::clicked, [=](){
          thread1->stopThread();
          thread1->wait();
      });
      

      2.Qt官方推薦做法,使用moveToThread函數(shù)
      點擊折疊或展開代碼
      // 任務(wù)類
      class Worker : public QObject
       {
           Q_OBJECT
       public slots:
           void doWork(const QString &parameter) {
               QString result;
               // 耗時操作
               // TODO
               emit resultReady(result);
           }
      
       signals:
           void resultReady(const QString &result);
       };
      
       // 外部調(diào)用
       class Controller : public QObject
       {
           Q_OBJECT
           // 使用智能指針列表
           QList<QPointer<QThread>> workerThreadList;
       public:
           Controller() {
               Worker *worker = new Worker;
         	  QPointer<QThread> workerThread = new QThread;
         	  // 加入管理列表
         	  workerThreadList.append(workerThread);
         	  // 將任務(wù)類移入線程
               worker->moveToThread(workerThread);
         	  // 連接信號
               connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
               connect(workerThread, &QThread::finished, workerThread, &QThread::deleteLater);
               connect(this, &Controller::operate, worker, &Worker::doWork);
               connect(worker, &Worker::resultReady, this, &Controller::handleResults);
         	  // 啟動線程
               workerThread->start();
           }
           ~Controller() {
               for (QPointer<QThread> thread : qAsConst(workerThreadList)) {
         	      if (! thread.isNull) {
         		      thread.quit();
         		      thread.wait();
         		  }
         	  }
           }
       public slots:
           void handleResults(const QString &);
       signals:
           void operate(const QString &);
       };
      

      3. 其他方法快速創(chuàng)建線程任務(wù)
      點擊折疊或展開代碼
      // QThread靜態(tài)函數(shù)create
      QThread *thread = QThread::create([=](){
          // 耗時操作
          // TODO
      });
      // QtConcurrent模塊,使用時需要在pro文件中引入QT += concurrent,使用頭文件#include <QtConcurrent>,可在幫助文檔中搜索 Concurrent Run
      QtConcurrent::run([=](){
          // 耗時操作
          // TODO
      });
      // QRunnable 除非有線程池的需求,否則個人不推薦使用。因為使用起來需要繼承和重寫,而且使用信號和槽比較麻煩
      MyRunnable *r = new MyRunnable;   // 需要繼承自QRunnable,重寫run函數(shù)
      QThreadPool threadpool;
      threadpool.setMaxThreadCount(1);
      threadpool.start(r);
      

      二、程序退出時如何退出正在運行的線程

      1. 在耗時的循環(huán)操作中添加標(biāo)志位的判斷,在退出時將標(biāo)志位設(shè)置成退出標(biāo)志位,比如上面的WorkThread1 示例中重寫的run函數(shù)中的處理方式,如果層級太多,該用全局變量就使用全局變量
      2. 翻閱幫助文檔發(fā)現(xiàn)QThread有以下兩個函數(shù),和標(biāo)志位差不多的用法
      點擊折疊或展開代碼
          // 請求中斷線程
          void QThread::requestInterruption()
          // 是否請求了中斷線程
          bool QThread::isInterruptionRequested() const
          
          // 使用方法
          // 當(dāng)中斷線程時,外部調(diào)用
          thread->requestInterruption();
          // 在線程的任務(wù)循環(huán)中添加判斷
          void long_task() {
            forever {
               if ( QThread::currentThread()->isInterruptionRequested() ) {
                   return;
               }
           }
       }
      

      三、處理異常情況程序退出后卻仍然在后臺掛起

      在接收到終止信號時,需要退出線程并且退出主線程,可能會因為子線程耗時太長導(dǎo)致程序在后臺掛起的情況(可能是這個原因),那么就需要先退出子線程,再退出主線程

      點擊折疊或展開代碼
      // 管理線程列表
      QList<QPointer<QThread>> mThreadList;
      // 創(chuàng)建智能指針
      QPointer<QThread> thread = new QThread;
      MyObject *obj = new MyObject;
      // 移入線程
      obj->moveToThread(thread);
      // 連接信號和槽
      connect(thread, &QThread::finished, obj, &MyObject::deleteLater);
      connect(thread, &QThread::finished, thread, &QThread::deleteLater);
      // 其他可能的線程正常退出的情況,自定義結(jié)束信號finished
      connect(obj, &MyObject::finished, [=](){
      	// TODO
         if (! thread.isNull) {
         	thread->quit();
         	thread->wait();
         }
      });
      
      // 程序結(jié)束時,循環(huán)阻塞,線程全退出后主線程退出
      while (mThreadList.size() > 0) {
             QPointer<QThread> thread = mThreadList.first();
             if ( ! thread.isNull()) {
                 thread->quit();
                 thread->wait();
             }
             mThreadList.pop_front();
         }
      qApp.exit();
      
      posted @ 2023-11-01 10:51  薄暮知秋  閱讀(1845)  評論(0)    收藏  舉報
      /*http://www.rzrgm.cn/lingr7/p/15651906.html*/ /*自動顯示目錄導(dǎo)航*/
      主站蜘蛛池模板: 亚洲精品美女一区二区| 无码av片在线观看免费| 国产在线观看码高清视频| 精品人妻中文字幕在线| 丰满少妇被猛烈进出69影院| 天堂a无码a无线孕交| 久久精品国产亚洲av忘忧草18| 久热re这里精品视频在线6| 一区二区中文字幕av| 777奇米四色成人影视色区| 国产粉嫩区一区二区三区| 午夜精品一区二区三区免费视频| 无码日韩人妻精品久久| 国产国语对白露脸正在播放| 欧美激情一区二区| 亚洲天堂在线观看完整版 | 免费无码成人AV片在线| 亚洲精品香蕉一区二区| 吉首市| 久久人人爽爽人人爽人人片av| 美女又黄又免费的视频| 亚洲中文字幕在线二页| av资源在线看免费观看| 青青草成人免费自拍视频| 欧美极品色午夜在线视频| 亚洲欧美人成电影在线观看| 精品人妻av区乱码| 伊人久久精品无码麻豆一区| 无码人妻斩一区二区三区| 竹山县| 亚洲中文字幕综合小综合| 国产亚洲一二三区精品| 思思热在线视频精品| 天堂va欧美ⅴa亚洲va在线| 蜜臀午夜一区二区在线播放| 中文字幕丰满乱子无码视频| 亚洲天堂亚洲天堂亚洲色图| 亚洲人成网站18禁止无码| 久久日韩在线观看视频| 国产麻豆放荡av激情演绎| 亚洲午夜伦费影视在线观看|