QThread
終了時に sを自動的に移動するように文書化QObject
されていないため、そのようなことはないとすでに結論付けることができると思います。このような動作は非常に驚くべきものであり、API の残りの部分とは相容れないものです。
完全を期すために、Qt 5.6 でテストしました。
QObject o;
{
QThread t;
o.moveToThread(&t);
for (int i = 0; i < 2; ++i)
{
t.start();
QVERIFY(t.isRunning());
QVERIFY(o.thread() == &t);
t.quit();
t.wait();
QVERIFY(t.isFinished());
QVERIFY(o.thread() == &t);
}
}
QVERIFY(o.thread() == nullptr);
QThread
aはスレッドではなく、スレッドを管理することを思い出してください。
がQThread
終了しても存在し続け、そこに存在するオブジェクトは存在し続けますが、イベントを処理しなくなります。を再起動するQThread
ことができ (推奨されません)、その時点でイベント処理が再開されます (そのため、同じQThread
スレッドが別のスレッドを管理している可能性があります)。
が破棄されるQThread
と、そこに存在していたオブジェクトはスレッド アフィニティを失います。ドキュメントはこれを保証しておらず、実際には「スレッドで作成されたすべてのオブジェクトが削除される前に、QThread
.
QtConcurrent::run()
ワーカー スレッドで関数を実行するを呼び出し、その関数で (後で使用するために) いくつかの QObject を動的に割り当てるとします。それらはワーカー スレッドで作成されたので、それらのスレッド アフィニティはワーカー スレッドのアフィニティである必要があります。ただし、ワーカー スレッドが終了すると、QObject スレッド アフィニティは無効になります。
このQThread
シナリオでは、 は終了しません。によって生成されたタスクがQtConcurrent::run
終了すると、そのタスクQThread
が実行されていた が に返さQThreadPool
れ、その後の への呼び出しによって再利用される可能性があり、QtConcurrent::run
に存在する はそこに存在QObject
しQThread
続けます。
QThreadPool::globalInstance()->setMaxThreadCount(1);
QObject *o = nullptr;
QThread *t = nullptr;
QFuture<void> f = QtConcurrent::run([&] {
o = new QObject;
t = o->thread();
QVERIFY(t == QThread::currentThread());
});
f.waitForFinished();
QVERIFY(t == o->thread());
QVERIFY(t->isRunning());
f = QtConcurrent::run([=] {
QVERIFY(t == QThread::currentThread());
});
f.waitForFinished();
オブジェクトを にQThread
戻す前に手動で から移動したいQThreadPool
場合や、 を使用しない場合がありますQtConcurrent::run
。QtConcurrent::run
タスクよりも長生きするタスク構造s を持つことQObject
は疑わしい設計であり、タスクは自己完結型であるべきです。@Mike が指摘したように、QThread
使用される にQtConcurrent::run
はイベント ループがありません。