QApplication is lazy (or makes other threads lazy in the application)

This is my first post here and I hope to find a solution to my problem. I started developing a Mac app using Qt. Now I am facing a huge and frustrating problem.

My problem is the QApplication event loop becomes lazy (or makes other threads lazy in the application) after 20-50 seconds. I tried to reproduce the same problem and came up with the code below.

So this is what I do. I am creating a new C ++ stream and the new stream prints the current time every 2 seconds. The problem comes after 10-30 iterations, some iterations take 6-12 seconds, which shouldn't be because I just slept 2 seconds on each iteration. I ran the code below and the result looks like this:

sumits-air:UbiqMac_qt Jay$ ./run.sh
"05.06.2015 16:43:30"
"05.06.2015 16:43:32"
"05.06.2015 16:43:34"
"05.06.2015 16:43:36"
"05.06.2015 16:43:38"
"05.06.2015 16:43:40"
"05.06.2015 16:43:42"
"05.06.2015 16:43:44"
"05.06.2015 16:43:46"
"05.06.2015 16:43:48"
"05.06.2015 16:43:50"
"05.06.2015 16:43:52"
"05.06.2015 16:43:54"
"05.06.2015 16:43:56"
"05.06.2015 16:43:58"
"05.06.2015 16:44:00"
"05.06.2015 16:44:02"
"05.06.2015 16:44:04"
"05.06.2015 16:44:06" (- 06 here)
"05.06.2015 16:44:18" (- 18 here. 12 seconds difference)
"05.06.2015 16:44:24" (- 24 here. 6 seconds difference)
"05.06.2015 16:44:26"
"05.06.2015 16:44:28"
"05.06.2015 16:44:30"
^C
sumits-air:UbiqMac_qt Jay$

      

When I run this program the same problem comes up every time. I'm not sure if the same problem would happen if someone tried to do this. But this is happening on my machine.

The code below works fine without QApplication. So please don't blame the C ++ thread or usleep or the kernel for thread management or so. Another weird thing: when I use QCoreApplication instead of QApplication, it works great. Also, I am using the same code in a ubuntu based machine and it works great with QApplication. I'm guessing this only happens on Mac (I haven't even tried Windows).

Please do not suggest using QThread, QTimer, or QTimer :: singleShot. I used them first and had the same problem. I used signals with QTimer and QThread and the problem was that signals were not generated in time or signals emitted in time but slots were not called in time. The delay was similar (6-12 seconds). In fact, this is why I use C ++ stream, because I thought using C ++ stream might solve the problem, but it doesn't.

Any help is appreciated.

OS: MAC OSX 10.9.5.

uname -a output:

Darwin 13.4.0 Darwin Kernel Version 13.4.0:
root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64

      

Code: main.cpp:

#include <QApplication>
#include <QDebug>
#include <QDateTime>

#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <thread>

void test() {
     while(true) {
          qDebug() << QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss");
          usleep(2000000);
     }
}

int main(int argc, char *argv[]) {
     QApplication a(argc, argv);
     std::thread *heartbeatThread = new std::thread(&test);
     a.exec();
     heartbeatThread->join();
     return 0;
}

      

test.pro:

QMAKE_CXXFLAGS += -std=c++11
QMAKE_CXXFLAGS += -stdlib=libc++
LIBS += -stdlib=libc++
QT += core gui widgets
TARGET = test
TEMPLATE = app
SOURCES += main.cpp

      

EDIT:

I solved my problem thanks to the same timing. I had a problem with the link provided the same day. It was an app sleep that was causing my app to sleep, so I had timer and sleep issues. The reason this only happens with QApplication and not QCoreApplication is because mac thinks I am using ui when I use QApplication. So when my app is inactive, the Mac can shutdown my app.

The workaround was to programmatically disable the application. I couldn't find an api in C / C ++ for it, but there is an api in lens c in this one. So I just named target c from C ++.

Has a header file c appnap.h:

#ifndef __APP_NAP__
#define __APP_NAP__

#if !defined(__cplusplus)
#define C_API extern
#else
#define C_API extern "C"
#endif

C_API void disableAppNap();
C_API void enableAppNap();

#endif

      

Then add appnap.m:

#include "appnap.h"
#include <Foundation/Foundation.h>

static id activity;

void disableAppNap() {
    activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityLatencyCritical | NSActivityUserInitiated 
                                                              reason:@"Disable App Nap"];
}

void enableAppNap() {
    [[NSProcessInfo processInfo] endActivity:activity];
}

      

Add these lines to your .pro file:

HEADERS += appnap.h
OBJECTIVE_SOURCES += appnap.m
LIBS += -framework Foundation

      

Then when you don't want the nap app to make your app sleep call disableAppNap before you start and call enableAppNap after your work is done.

This solved my problem.

0


source to share


1 answer


Sounds the same as the problem described here, in which case the solution to disable Apple power - the "merge timer" economy (obviously introduced in 10.9) may help you.



(If QApplication is causing a specific problem, perhaps because its C ++ widget support calls some old Mac API that really needs an upgrade to Mac Grand Central Dispatch. If you're on recent Qt - tried the 5.5 beta? - and, seeing this it might be worth writing a bug report . But really, especially for a "new application", you should consider getting C ++ for QGuiApplication and the wonderful world of QtQuick UI).

+2


source







All Articles