C++ 如何将要在Qt应用程序中执行的函数排队';s的主线程具有尽可能高的优先级?

C++ 如何将要在Qt应用程序中执行的函数排队';s的主线程具有尽可能高的优先级?,c++,multithreading,qt,C++,Multithreading,Qt,我希望能够在Qt应用程序的主线程中以尽可能高的优先级执行一个单独的线程队列astd::function,这意味着执行此函数优先于主线程中发生的任何其他事情,主线程当前执行的任何任务除外。(澄清一下,主线程中当前正在执行的任务不需要产生执行或诸如此类的结果。这个排队函数应该是线程处理的下一个事件,延迟越小越好。) 线程可以通过多种方式设置要在另一个特定的QThread中调用的函数,例如使用具有零秒间隔的单次QTimer,或者使用QMetaObject::invokeMethod。但我不确定函数的执

我希望能够在Qt应用程序的主线程中以尽可能高的优先级执行一个单独的线程队列a
std::function
,这意味着执行此函数优先于主线程中发生的任何其他事情,主线程当前执行的任何任务除外。(澄清一下,主线程中当前正在执行的任务不需要产生执行或诸如此类的结果。这个排队函数应该是线程处理的下一个事件,延迟越小越好。)

线程可以通过多种方式设置要在另一个特定的
QThread
中调用的函数,例如使用具有零秒间隔的单次
QTimer
,或者使用
QMetaObject::invokeMethod
。但我不确定函数的执行相对于主线程正在处理的其他任务的优先级

我的第一个想法是创建一个自定义
QEvent
,其中包含我要执行的函数的一个实例,为执行该函数的新自定义事件类型编写一个处理程序,然后使用如下方式发布它:

qApp->postEvent(qApp, customEvent, Qt::HighEventPriority * 1000000);
…或使用其他合适的大整数作为事件优先级。我不确定这是否是最好的方法,因为我对Qt的事件系统如何工作没有深入的了解。(比如,相对于发送到其他
QObject
,其线程关联设置为主线程的事件,这将如何划分优先级?)


有更好的方法吗?

以下是我确定的解决方案:

#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();
}
#定义kFunctionEventType((QEvent::Type)(QEvent::User+1))
类FunctionEvent:公共QEvent{
公众:
FunctionEvent(const std::function&inFunc):QEvent(kFunctionEventType),func(inFunc){};
std::函数func;
};
类函数EventReceiver:公共QObject{
Q_对象
公众:
显式函数eventreceiver():QObject(nullptr){};
虚拟布尔事件(QEvent*事件);
};
静态函数EventReceiver*函数EventReceiver()
{
静态功能事件接收器;
返回和接收;
}
bool FunctionEventReceiver::事件(QEvent*事件)
{
如果(事件->类型()!=kFunctionEventType){
返回QObject::event(事件);
}
FunctionEvent*FunctionEvent=(FunctionEvent*)事件;
functionEvent->func();
functionEvent->accept();
返回true;
}
void executeInMainThreadWithMaximumPriority(常量std::function&func)
{
FunctionEvent*event=新的FunctionEvent(func);
qApp->postEvent(functionEventReceiver(),事件,INT_MAX);
}
void initialize()
{
//确保在主线程中创建接收器:
函数eventreceiver();
}

一个警告是,我必须在我的应用程序开始时调用
initialize()
,以确保事件接收器已创建并与应用程序的主线程关联。

如果您不想将
QApplication
子类化(我同意,除非绝对必要,否则您可能不想这样做),签出
QObject::installEventFilter(QObject*)
。您可以调用
qApp->installEventFilter(whateverObjectYouWant)
以便
whateverObjectYouWant
对象在
QApplication
对象收到高优先级事件时调用其
eventFilter()
方法。请参阅:关于事件优先级:Qt文档说事件总是按优先级降序传递的,因此,如果您将优先级设置为
INT\u MAX
,则应保证在主线程返回事件循环后,您的事件将第一个被传递,最好的设计是,GUI输入队列永远不会过载:)听起来很奇怪。。。请注意,主线程是一个GUI线程。您需要执行什么样的任务来避免事件队列?我认为您可能问了一个错误的问题,也称为“XY问题”。特别是,如果你描述了你想要实现的目标,以及为什么你认为你所描述的行为解决了这个问题,那就更清楚了。