1

1 つのワーカー スレッドを使用する単純なアプリケーションがあります。このワーカー スレッドが開始され、ネットからのファイルのダウンロードを担当する DownloadManager が初期化されます。私のメイン アプリケーション クラスでは、DownloadManager が終了する前に発行されるスレッドに finished() SIGNAL があります。

私の質問は、DownloadManager が作業を終了するまでワーカー スレッドを待機させる方法です。

コード例は次のとおりです。

 class Main
 {
     m_DownloadWorker = new DownloadWorker(this);
     QObject::connect(pm_hotosDownloadWorker, SIGNAL(finished()), this, SLOT(DownloadWorkerFinished()));
     m_DownloadWorker->Execute();
     // do i need to do here something so the thread will wait ?

     .....


    void Main::DownloadWorkerFinished()
    {
        Log("DownloadWorkerFinished");
    }
 };


 class DownloadWorker : public QThread
 {
     void DownloadWorker::Execute()
     {

         // do i need to do here somthing so the thread will wait ? 
        start();
     }

     void DownloadWorker::run()
     {
         // do i need to do here somthing so the thread will wait ?
        DownloadManager* pDownloadManager = new DownloadManager(this);
        pDownloadManager->download();


     }
 };

 class DownloadManager: public QObject
 {
     // downloading stuff using Qt networkmanager 

     .....
     .....
 }
4

2 に答える 2

5

非同期操作が完了したときに発行されるシグナルがある場合は、常に QEventLoop を使用して、非同期操作を現在のスレッドとの同期に「変える」ことができます。まだ非同期ですが、スレッドは終了するまで「待機」します。

QNetworkAccessManager nam;
QEventLoop loop;
QNetworkReply *reply = nam.get(request); 
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();

したがって、基本的には、ネットワーク要求を同期的に実行する DownloadManager クラスにこれを配置します。exec()ループのquitスロットが呼び出されると戻ります。

于 2011-04-10T09:18:58.020 に答える
3

QThread::exec()呼び出しを使用して、イベント ループでスレッドを実行できます。QThread::exit()を呼び出してスレッドを終了するように指示するまで、スレッドはそれを実行します。したがって、サンプルコードは次のようになります。

void DownloadWorker::run()
 {
    DownloadManager* pDownloadManager = new DownloadManager(this);
    connect(pDownloadManager, SIGNAL(finished()), SLOT(exit()));
    connect(pDownloadManager, SIGNAL(error()), SLOT(exit()));
    pDownloadManager->download();
    exec();
 }

これにより、DownloadManager の「finished()」シグナルが発行されるまで、スレッドが終了しないことが保証されます。

注: ここでは、問題を解決する方法の例を示しますが、アプリ コード全体はわかりません。つまり、このコードがスレッド セーフで一貫性があるという保証はありません。ミューテックスとすべての正しい同期を自分で処理する必要があります。十分気をつける !このような「低レベル」スレッド API を使用するには、マルチスレッドについて十分に理解している必要があります。

それが役立つことを願っています

于 2011-04-10T18:29:13.900 に答える