【问题标题】:Qt Process Events processing for longer than specifiedQt Process Events 处理时间超过指定时间
【发布时间】:2016-05-30 20:22:54
【问题描述】:

我遇到了一些问题,我不知道该怎么办。

我正在运行 Qt 4.8.6,Qt creator 3.3.2,Ubuntu 12.04 中的环境交叉编译到运行 Debian 7 内核 3.8.13 的 Beaglebone Black。

我看到的问题是这段代码:

if (qApp->hasPendingEvents())
{
    qDebug() << "pending events";
}
qApp->processEvents(QEventLoop::AllEvents, 10);

根据(至少我对)Qt 文档的解释,它不能正常工作。我希望进程事件循环最多在指定的 10 毫秒内起作用。

发生的情况是永远不会打印 qDebug 语句。然后,我希望因此没有要处理的事件,并且流程事件语句的进出速度非常快。大多数时候都是这样。

会发生什么(不是每次,但经常发生)qDebug 语句被跳过,processEvents 语句执行 1 到 2 秒。

有什么方法可以让我深入了解进程事件中发生的事情并找出导致延迟的原因?

【问题讨论】:

  • 我没有看到你的其余代码,但看起来你正在编写伪同步意大利面条代码,而在你的代码中的其他地方这可能会让你反感。您正在某处执行一项操作,该操作会阻塞 1-2 秒。当你重新进入事件循环时,任何现有的超时都会被忽略,所以如果这个processEvents 调用你的代码再次调用processEvents,你就有麻烦了。一般来说,您可以编写干净的异步代码,而无需任何processEvents 调用。
  • 一般来说,如果您希望在给定时间后重新获得控制权,您应该为此使用计时器。然后,您将不会与重入问题或处理时间“太长”的系统事件作斗争 - 或者,至少,您将尽最大努力尽早控制您的代码。

标签: c++ qt qt4


【解决方案1】:

Qt 处理事件的时间超过了在 Linux 上为 QApplication::processEvents 调用指定的时间 系统。有什么方法可以让我深入了解 处理事件并找出导致延迟的原因?

是的,观察 Qt 源代码可能会有所帮助。源代码在/home/myname/software/Qt/5.5/Src/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp 或者附近的某个地方:

bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
{
    Q_D(QEventDispatcherUNIX);
    d->interrupt.store(0);

    // we are awake, broadcast it
    emit awake();

    // This statement implies forcing events from system event queue
    // to be processed now with doSelect below
    QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);

    int nevents = 0;
    const bool canWait = (d->threadData->canWaitLocked()
                          && !d->interrupt.load()
                          && (flags & QEventLoop::WaitForMoreEvents));

    if (canWait)
        emit aboutToBlock();

    if (!d->interrupt.load()) {
        // return the maximum time we can wait for an event.
        timespec *tm = 0;
        timespec wait_tm = { 0l, 0l };
        if (!(flags & QEventLoop::X11ExcludeTimers)) {
            if (d->timerList.timerWait(wait_tm))
                tm = &wait_tm;
        }

        if (!canWait) {
            if (!tm)
                tm = &wait_tm;

            // no time to wait
            tm->tv_sec  = 0l;
            tm->tv_nsec = 0l;
        }
        // runs actual event loop with POSIX select
        nevents = d->doSelect(flags, tm);

似乎有系统发布的事件没有考虑到qApp-&gt;hasPendingEvents()。然后QCoreApplicationPrivate::sendPostedEvents(0, 0, d-&gt;threadData); 刷新那些要由d-&gt;doSelect 处理的事件。如果我正在解决这个任务,我会尝试刷新那些发布的事件out,或者可能意识到flags 参数是否以及为什么设置了QEventLoop::WaitForMoreEvents 位。我通常要么从源代码构建 Qt,要么提供调试器及其符号/源的路径,以便可以在那里挖掘。

附:我浏览了 Qt 5.5.1 源事件处理代码,但这应该与您处理的非常相似。或者那个实现实际上是bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)?在实际系统上很容易找到。

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    相关资源
    最近更新 更多