6

Qt のワーカー スレッドの単純な側面であると私が信じていることを確認したいと思います。

対応するスレッドで時間のかかる作業を管理することを目的とする QThread を作成するとします。start()さらに、 QThreadを呼び出して、このスレッドの対応するイベント ループを実行できるようにするとします。作業自体は、QThread のシグナルによって通知されるメンバー関数 (スロット) によって実行されstarted()ます。

つまり(https://stackoverflow.com/a/11039216/368896からコピー):

class Task : public QObject
{
Q_OBJECT
public:
    Task();
    ~Task();
public slots:
    void doWork()
    {
        //very time-consuming code is executed here before the next line is reached...
        emit workFinished(); // Calls workFinished() signal (after a long time)
    }
signals:
    void workFinished();
};

// ... in the main thread:
QThread *thread = new QThread( );
Task    *task   = new Task();
task->moveToThread(thread);
connect( thread, SIGNAL(started()), task, SLOT(doWork()) );
connect( task, SIGNAL(workFinished()), thread, SLOT(quit()) );
//automatically delete thread and task object when work is done:
connect( thread, SIGNAL(finished()), task, SLOT(deleteLater()) );
connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
thread->start();

私の質問は次のとおりです。インスタンスのスロットfinished()を呼び出すために、ワーカー スレッドのイベント ループがシグナルからトリガーを受け取ることを理解しています。また、このイベント ループは、関数が返された直後に実行されるため、関数の最後の呼び出しによってワーカー スレッドのイベント キューに追加されたシグナルからのトリガーを処理する準備が整い、使用可能になります。 .deleteLater()taskdoWork()finished()finished()doWork()

doWork()内部で実行される時間のかかる操作の全過程(発行finished()される前とdoWork()関数が終了する前) の間、ワーカー スレッド内のイベント ループがスロット関数でブロックされていることを確認したいと思いdoWork()ます。したがって、ワーカー スレッドは時間のかかる関数の実行中に、イベント ループのスレッドが所有するオブジェクトでトリガーされたスロットに応答しないでください。(したがって、そのようなスロットは終了後、ワーカー スレッドのイベント ループが再びアクティブになると、シグナルからのトリガーが処理される前にdoWork()のみ実行されます。)doWork()finished()

これは事実だと思いますが、確認したいと思います。

ありがとう!

4

1 に答える 1

7

ワーカー スレッドのイベント ループがブロックされます。つまり、イベントを処理できなくなります (シグナルとスロット間の「キューに入れられた」接続に使用されるイベントを含む)。イベントループオブジェクトへの呼び出しを自分で明示的にトリガーしない限り。

ただし、ワーカー スレッドから発行されたシグナルによってトリガーされたスロットをワーカー スレッドで実行することはできます。これらは単純な関数呼び出しであり、実行中のイベント ループを必要としないためです。

于 2013-06-07T17:32:09.917 に答える