문제:
Qt에서는 GCD와 유사한 이벤트 루프가 있는 스레드에서 람다 또는 펑터를 실행하려고 합니다. Objective-C에서 대기열을 전달합니다.
해결책:
솔루션은 원하는 스레드에 있는 소비자 개체에 펑터를 래핑하는 이벤트를 전달하는 데 중점을 둡니다. 이 작업을 메타콜 게시라고 하며 여러 가지 방법으로 구현할 수 있습니다.
Qt 5.10 & Up TL;DR:
QObject 또는 QThread에서 메소드를 호출할 수 있습니다. 직접:
// 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), []{ ... });
Functor용 TL;DR:
Functor를 적절한 이벤트 개체에 래핑하기 위해 여러 템플릿 함수가 제공되므로 메타콜 게시가 편리해집니다.
// 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 스레드에서 Functor 또는 Lambda를 실행하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!