ホームページ >バックエンド開発 >C++ >GCD と同様に、特定の Qt スレッドでファンクターまたはラムダを実行するにはどうすればよいですか?

GCD と同様に、特定の Qt スレッドでファンクターまたはラムダを実行するにはどうすればよいですか?

DDD
DDDオリジナル
2024-12-16 18:35:12137ブラウズ

How to Execute Functors or Lambdas in a Specific Qt Thread, Similar to GCD?

GCD スタイルの Qt で指定されたスレッドでファンクターまたはラムダを実行する方法?

問題:

Qt では、次のようなイベント ループを持つスレッドでラムダまたはファンクターを実行したいとします。 Objective-C の GCD のディスパッチ キュー。

解決策:

この解決策は、ファンクターをラップするイベントを目的のスレッドに存在するコンシューマー オブジェクトに配信することを中心としています。この操作は メタコール ポスティング と呼ばれ、いくつかの方法で実装できます。

Qt 5.10 以降 TL;DR:

QObjects または QThreads でメソッドを呼び出すことができます直接:

// Invoke on the main thread
QMetaObject::invokeMethod(qApp, []{ ... });

// Invoke on an object's thread
QMetaObject::invokeMethod(obj, []{ ... });

// Invoke on a particular thread
QMetaObject::invokeMethod(
    QAbstractEventDispatcher::instance(thread),
    []{ ... });

ファンクターの TL;DR:

適切なイベント オブジェクトでファンクターをラップするためのいくつかのテンプレート関数が提供されており、メタコールの投稿が便利です。

// Post to the main thread sync
void execInMainThread_sync(std::function<void(void)> func) {
    if(qApp->thread() == QThread::currentThread())
        func();
    else {
        ((App*) qApp)->invokeGenericExec(func, Qt::BlockingQueuedConnection);
    }
}

// Post to the main thread async
void execInMainThread_async(std::function<void(void)> func) {
    ((App*) qApp)->invokeGenericExec(func, Qt::QueuedConnection);
}

TL;DR 用メソッド/スロット:

メソッドまたはスロットの場合、メタコールの投稿を処理するマクロが定義されています。

#define POST_METHOD(obj, method) \
    QObject src; \
    QObject::connect(&src, &QObject::destroyed, obj, method, \
                       Qt::QueuedConnection);

共通コード:

提供されたコードには、さまざまな環境で使用するためにメタコール投稿実装を抽象化する共通のヘルパー関数とマクロが含まれています。

例:

void test1() {
    QThread t;
    QObject o;
    o.moveToThread(&t);

    // Execute in given object's thread
    postToObject([&]{ o.setObjectName("hello"); }, &o);
    // or
    postToObject(std::bind(&QObject::setObjectName, &o, "hello"), &o);

    // Execute in given thread
    postToThread([]{ qDebug() << "hello from worker thread"; });

    // Execute in the main thread
    postToThread([]{ qDebug() << "hello from main thread"; });
}

補足:

ターゲット スレッドにイベント ループがない場合ワーカー スレッドなど、スレッド内でイベント ループを開始するメカニズムが必要になる場合があります。たとえば、メタコールの投稿にシングルショット タイマーを使用する場合、QThread::exec() を使用してイベント ループを開始できます。

以上がGCD と同様に、特定の Qt スレッドでファンクターまたはラムダを実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。