2016-05-30 3 views
0

У меня есть проблема, и я не уверен, что с этим делать.Обработка событий процесса Qt дольше, чем указано

Я запускаю Qt 4.8.6, создатель Qt 3.3.2, среда в Ubuntu 12.04 перекрестная компиляция на Beaglebone Black работает Debian 7 kernel 3.8.13.

Вопрос, который я вижу, что этот код:

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

не работает, как это должно в соответствии с (по крайней мере моей интерпретации) сдаточной документации Qt. Я ожидал бы, что цикл событий процесса будет работать для AT MOST с указанными 10 миллисекундами.

Что происходит, инструкция qDebug никогда не печатается. Тогда я ожидал, что нет никаких событий, которые нужно обработать, и процесс событий заходит очень быстро. В большинстве случаев это так.

Что происходит (не каждый раз, но достаточно часто) оператор qDebug пропускается, а инструкция processEvents выполняется где-то между 1 и 2 секундами.

Есть ли способ, которым я могу вникать в то, что происходит в событиях процесса, и выяснить, что вызывает задержку?

+0

Я не вижу остальную часть вашего кода, но похоже, что вы пишете псевдосинхронный код спагетти, а где-то еще в вашем коде это может укусить вас. Вы выполняете операцию где-то, которая блокирует эти 1-2 секунды. Когда вы повторно вводите цикл событий, любые существующие таймауты игнорируются, поэтому, если этот 'processEvents' вызывает ваш код, который снова вызывает' processEvents', у вас проблемы. Вообще говоря, вы можете написать чистый асинхронный код без каких-либо вызовов 'processEvents'. –

+0

Вообще говоря, если вы хотите восстановить контроль через определенное время, вы должны использовать для этого таймер. Вы не будете сражаться с проблемами реентерации или с системными событиями, обработка которых занимает слишком много времени - или, по крайней мере, вы будете делать все возможное, чтобы сохранить свой код под контролем как можно раньше. –

ответ

0

Qt обрабатывает события дольше, чем указано для QApplication::processEvents вызова на системы Linux. Есть ли способ, с помощью которого я могу вникнуть в происходящее в событиях процесса и выяснить, что вызывает задержку?

Да, соблюдение исходного кода 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->hasPendingEvents(). И затем QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); очищает те события, которые будут обработаны d->doSelect. Если бы я решал эту задачу, я попытался либо сбросить те опубликованные события из, либо, может быть, реализовать, если и почему параметр flags имеет QEventLoop::WaitForMoreEvents бит. Обычно я либо строю Qt из исходного кода, либо предоставляю отладчику путь к его символам/источнику, поэтому там можно копать.

P.S. Я взглянул на код обработки исходного кода Qt 5.5.1, но это должно быть очень похоже на то, с чем вы имеете дело. Или может ли эта реализация действительно быть bool QEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)? Его можно найти в реальной системе.

Смежные вопросы