Это мой первый пост здесь, и я надеюсь найти решение моей проблемы. Я начал разрабатывать приложение для Mac с использованием Qt. Я сталкиваюсь с огромной и расстраивающей проблемой прямо сейчас.
Моя проблема в том, что цикл событий QApplication становится ленивым (или делает другие потоки ленивыми в приложении) через 20-50 секунд. Я попытался повторить ту же проблему и придумал код ниже.
Так вот что я делаю. Я создаю новый поток c ++, и новый поток печатает текущее время каждые 2 секунды. Проблема в том, что после 10-30 итераций некоторые итерации занимают 6-12 секунд, чего не должно быть, потому что я просто сплю 2 секунды в каждой итерации. Я запустил код ниже, и результат выглядит так:
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$
Когда я запускаю эту программу, каждый раз возникает одна и та же проблема. Я не уверен, случится ли такая же проблема, если кто-то попытается это сделать. Но это происходит в моей машине.
Код ниже без QApplication работает нормально. Поэтому, пожалуйста, не обвиняйте поток c ++ или usleep или ядро в управлении потоками или что-то в этом роде. Другая странная вещь заключается в том, что когда я использую QCoreApplication вместо QApplication, он также работает нормально. Кроме того, я использую тот же код на компьютере на основе Ubuntu, и он отлично работает с QApplication. Я думаю, это происходит только на Mac (хотя я не пробовал Windows).
Пожалуйста, не предлагайте использовать QThread, QTimer или QTimer :: singleShot. Сначала я их использовал, и у меня возникла та же проблема. Я использовал сигналы с QTimer и QThread, и проблема заключалась в том, что сигналы не излучались во времени или сигналы излучались во времени, но слоты не вызывались во времени. Задержка была аналогичной (6 — 12 секунд). Собственно, именно поэтому я использую нить c ++, потому что я думал, что нить c ++ может решить проблему, но это не так.
Любая помощь приветствуется.
ОС: MAC OSX 10.9.5.
uname -a вывод:
Darwin 13.4.0 Darwin Kernel Version 13.4.0:
root:xnu-2422.115.4~1/RELEASE_X86_64 x86_64
Код:
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
РЕДАКТИРОВАТЬ:
Я решил свою проблему благодаря Timday. У меня была проблема в ссылке, которую предоставил Timday. Это был сон приложения, который заставлял мое приложение спать, поэтому у меня были проблемы с таймером и сном. Причина, по которой это происходит только с QApplication, но не с QCoreApplication, заключается в том, что mac думает, что у меня есть пользовательский интерфейс, когда я использую QApplication. Поэтому, когда мое приложение не активно, Mac может перевести мое приложение в спящий режим.
Обходной путь должен был отключить приложение сна программно. Я не могу найти API в C / C ++ для него, но в этом есть цель API в этом ссылка на сайт. Так что я просто назвал цель c из c ++.
Есть 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
Тогда есть 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];
}
Добавьте эти строки в ваш файл .pro:
HEADERS += appnap.h
OBJECTIVE_SOURCES += appnap.m
LIBS += -framework Foundation
Затем, когда вы не хотите, чтобы app nap отключил ваше приложение, вызовите disableAppNap до начала вашей операции и вызовите enableAppNap после ее завершения.
Это решило мою проблему.
Звучит много как описанная проблема Вот, в этом случае решение Отключение энергосберегающего «слияния таймера» Apple (очевидно, введенного в 10.9) может вам помочь.
(Если QApplication определенно вызывает проблему, возможно, это связано с тем, что его поддержка виджетов C ++ вызывает некий старый Mac API, который действительно необходимо обновить до Grand Central Dispatch для Mac. Если вы недавно работали с Qt — пробовали бета-версию 5.5? — и видите это, возможно, стоит подать сообщение об ошибке. Но на самом деле, особенно для «нового приложения», вы должны рассмотреть возможность отключения виджетов C ++ для QGuiApplication и замечательного мира пользовательского интерфейса QtQuick).