0

2 つのクラスがあります。1 つはメイン スレッドで実行されて GUI 操作を実行し、もう 1 つは計算を実行してネットワーク リクエストを作成します。

// A member of the class that runs in the main thread
QThread thread;

以下は、メイン スレッドで実行されるクラスの初期化メソッドの抜粋です。

// Create the class that runs in the other thread and move it there
CServerThread * server = new CServerThread;
server->moveToThread(&thread);

// When the thread terminates, we want the object destroyed
connect(&thread, SIGNAL(finished()), server, SLOT(deleteLater()));
thread.start();

メインスレッドで実行されるクラスのデストラクタで:

if(thread.isRunning())
{
    thread.quit();
    thread.wait();
}

私が期待しているのは、スレッドが終了し、CServerThreadクラスのインスタンスを破棄することです。ただし、CServerThreadクラスのデストラクタは呼び出されていません。

4

1 に答える 1

5

QThread::quit()そのスレッドのイベント ループを停止します。

スレッドのイベント ループに、リターン コード 0 (成功) で終了するように指示します。

ただしQObject::deleteLater()、「所有している」スレッドをアクティブにするには、イベント ループが必要です。

このオブジェクトの削除をスケジュールします。
制御がイベント ループに戻ると、オブジェクトは削除されます。

そのため、オブジェクトのデストラクタは実行されず、finishedシグナルが発生するのが遅すぎます。

以下の不自然な例を考えてみましょう:

#include <QThread>
#include <iostream>

class T: public QObject
{
    Q_OBJECT

    public:
        QThread thr;
        T() {
            connect(&thr, SIGNAL(finished()), this, SLOT(finished()));
        };
        void start() {
            thr.start();
            std::cout << "Started" << std::endl;
        }
        void stop() {
            thr.quit();
            std::cout << "Has quit" << std::endl;
        }
        void end() {
            thr.wait();
            std::cout << "Done waiting" << std::endl;
        }
    public slots:
        void finished() {
            std::cout << "Finished" << std::endl;
        }
};

あなたが呼び出す場合:

T t;
t.start();
t.stop();
t.end();

出力は次のようになります。

Started
Has quit
Done waiting
Finished

finishedが行われた後にトリガーさwaitれます。接続が有効になるには遅すぎますdeleteLater。そのスレッドのイベント ループは既に停止しています。

于 2011-10-23T07:31:20.100 に答える