3

私はリンクをたどっていました

  1. それは間違っている
  2. QThread の正しい使い方 Part1
  3. QThread の正しい使い方 Part2

いくつかのステートメントに混乱しました。最初のリンクでは、

QThread のすべての関数は、QThread が開始するスレッドではなく、作成中のスレッドから呼び出されるように記述され、意図されています。

moveToThreadサブクラス化する代わりに、オブジェクトを新しいスレッドに移動するために使用することを提案していますQThread。私の質問は:

イベント ループを作成するrunメソッド呼び出しのデフォルトの実装と、オブジェクトのスレッド アフィニティが を使用して変更されると、すべてが作成スレッドではなく新しいスレッドで実行されます。これは、前述の使用目的と矛盾します。何か不足していますか?execmoveToThreadslots

2 番目の質問:

3番目のリンクでは、

イベント キューはイベント ループではなくスレッドに属し、このスレッドで実行されているすべてのイベント ループによって共有されます。

私の質問は、1 つのスレッドに複数のイベント ループが存在する方法です。私が理解しているのは、/が呼び出されるまでevent -loopがevent-queueをループし、各プロセスがそのキューに到着することです。これが真の場合、( /が呼び出されない限り) 1 つのループが終了することはありません。別のループを開始するにはどうすればよいでしょうか? それを示すサンプルコードは高く評価されます。exitterminateeventexitterminate

4

1 に答える 1

4

「これは前述の使用目的と矛盾しています。何か不足していますか?」

はい、スレッド アフィニティ (オブジェクトが実行されているスレッド) の概念を誤解していると思います。

最小限のコードで例を見てみましょう: -

QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread);   // MyObject on the new thread, controlled by pThread
pThread->start();               // pThread instance is still on the main thread

このコードが、スレッド アフィニティがメイン スレッドであるオブジェクトから作成されたと仮定するとQMainWindow、スレッド オブジェクトpThreadはメイン スレッドで実行されます。そのスレッド アフィニティはメイン スレッドです。

対照的に、QObject派生MyObjectインスタンスmyObjは新しいスレッド に移動されましたpThread。そのため、 のスレッド アフィニティはmyObj新しいスレッドになりました。

" のために書かれた " 関数QThreadは、メイン スレッドが実行されている場所であるため、メイン スレッドから直接呼び出されます。

QThreadスレッド自体ではなく、スレッド コントローラー オブジェクトと考えてください。これは、 が基になるスレッドを管理するQThread方法を変更したくない場合を除いて、 からの継承がしばしば推奨されない理由の 1 つです。QThread

1 つのスレッドに複数のイベント ループが存在する方法は?...

私はこれを自分で直接使用したことはありませんが、理解したとおりに説明しようとします。おそらく、他の誰かがこれを修正または確認できるでしょう。QEventLoopのQt ドキュメントから、次のように述べています。

いつでもQEventLoopオブジェクトを作成し、それを呼び出しexec()てローカル イベント ループを開始できます。

QEventLoop exec からの署名は次のとおりです。

int QEventLoop::exec ( ProcessEventsFlags フラグ = AllEvents )

したがって、一連のフラグを渡すと、これらのイベントのみが処理されます。呼び出しによって が呼び出されるexec()までイベントの処理が開始さexit()れるため、1 つ以上の特定のイベントが発生するまでプログラムを待機させるローカル イベント ループを作成できます。

2 番目のイベント ループは、メイン イベント ループ内のローカル イベント ループですが、各イベント ループは、スレッド内のすべてのイベント ループによって共有されるイベント キュー全体を処理できるため、メイン イベントからのイベント処理をオーバーライドするために使用できます。ループ。

イベント ループを次のように概念化すると (疑似コード): -

QList<QEvent*> eventList;
while(!stop)
{
    // handle events in eventList
}

2 番目のイベント ループは次のようになります。

bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
    // handle events in eventList
    ...
    ...
    // Inner event loop
    bool bStop = false;
    while(!bStop)
    {
        // handle events in eventList
    }
}
于 2014-05-29T12:57:52.720 に答える