Qtアプリケーションのメインスレッドで実行される関数をできるだけ高い優先度でキューに入れるにはどうすればよいですか?

GuyGizmo

std::functionQtアプリケーションのメインスレッドで実行される別のスレッドキューをできるだけ高い優先度で実行できるようにしたいと思います。つまり、この関数の実行は、メインスレッドで発生している他のすべてのものよりも優先されます。メインスレッドが現在実行しているタスク。(明確にするために、メインスレッドで現在実行中のタスクは、実行などを行う必要はありません。このキューに入れられた関数は、スレッドができるだけ遅延せずに処理する次のイベントである必要があります。)

スレッドが別の特定の関数で呼び出される関数を設定する方法はいくつかありますQThread。たとえばQTimer、ゼロ秒間隔のシングルショットを使用したり、を使用したりしQMetaObject::invokeMethodます。しかし、メインスレッドによって処理されている他のタスクとの関係で、関数の実行がどのように優先されるかはわかりません。

私が最初に考えたのは、QEvent実行したい関数のインスタンスを含むカスタムを作成し、その関数を実行する新しいカスタムイベントタイプのハンドラーを作成して、次のようなものを使用して投稿することでした。

qApp->postEvent(qApp, customEvent, Qt::HighEventPriority * 1000000);

...またはイベントの優先度に他の適切な巨大な整数を使用します。Qtのイベントシステムがどのように機能するかについての深い知識がないため、これがこれを行うための最良の方法であるかどうかはわかりません。QObjectスレッドアフィニティがメインスレッドに設定されている他のにディスパッチされたイベントに関して、これはどのように優先されますか?)

より良い方法はありますか?

GuyGizmo

これが私が決めた解決策です:

#define kFunctionEventType ((QEvent::Type)(QEvent::User + 1))

class FunctionEvent : public QEvent {
public:
    FunctionEvent(const std::function<void()> &inFunc) : QEvent(kFunctionEventType), func(inFunc){};
    std::function<void()> func;
};

class FunctionEventReceiver : public QObject {
    Q_OBJECT
public:
    explicit FunctionEventReceiver() : QObject(nullptr) {};
    virtual bool event(QEvent *event);
};

static FunctionEventReceiver * functionEventReceiver()
{
    static FunctionEventReceiver receiver;
    return &receiver;
}

bool FunctionEventReceiver::event(QEvent *event)
{
    if (event->type() != kFunctionEventType) {
        return QObject::event(event);
    }
    
    FunctionEvent *functionEvent = (FunctionEvent *)event;
    functionEvent->func();
    functionEvent->accept();
    
    return true;
}

void executeInMainThreadWithMaximumPriority(const std::function<void ()> &func)
{
    FunctionEvent *event = new FunctionEvent(func);
    qApp->postEvent(functionEventReceiver(), event, INT_MAX);
}

void initialize()
{
    // Ensures receiver is created in main thread:
    functionEventReceiver();
}

1つの注意点はinitialize()、アプリの起動時に呼び出して、イベントレシーバーが作成され、アプリケーションのメインスレッドに関連付けられていることを確認する必要があることです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ