Название: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 08, 2010, 17:16 Доброго времени суток!
Возникла задача предварительно проанализировать: какой из типов таймеров использовать в приложении. Суть в том, что в приложении (к примеру) будут использоваться некие объекты (назовем их "Коммуникационные ресурсы", наследованы от QIODevice), которые выполняют прием/передачу данных через сокеты и т.п... Так вот, при обмене данными планирую использовать асинхронный режим. Всё хорошо, но необходимо организовать обмен типа запрос/ответ, т.е. после записи данных в ресурс необходимо засекать время ожидания ответа из ресурса. т.е. по истечении некоторого времени если ресурс не ответил, то формировать ошибку и т.п. Самих объектов "ресурс" может быть сотни/тысячи и создавать столько же таймеров - абсурд. Пока что единственный выход (ИМХО) - создать один многоканальный таймер в котором каналы представляли бы собой обычные счетчики, значения в которых инкрементировались каждый раз при поступлении сигнала от этого таймера. Но что думают гуру? :) Может что лучше предложат? Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: asvil от Декабрь 08, 2010, 17:39 Не могу назвать себя гуру. Но я бы реализовал то, что Вы предложили. Список счетчиков. После некоторой записи добавлять счетчик со значением таймаута. В таймере пройти по всем счетчикам, декрементировать каждый. В процессе декрементации нулевые выбрасывать ну и в куда-то генерировать таймаут.
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 08, 2010, 19:31 Цитировать Не могу назвать себя гуру. Но я бы реализовал то, что Вы предложили. Список счетчиков Да, но это все-таки какое-то кривоватенькое решение, хотя.. надо проверить.В принципе, меня устроил бы таймер QObject-а, но оно что-то уж очень много кушает ресурсов. Я тут на скорую руку сделал тестовый примерчик: myobject.h Код: #ifndef MYOBJECT_H main.cpp Код: #include <QtCore/QCoreApplication> в котором создается 10000 объектов, в каждом из которых инициализируется таймер с интервалом ~1мс... При запуске всего этого, одно из двух ядер процессора загружается на ~70%, другое ~50%. Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 08, 2010, 22:17 Наспех соорудил класс MultiChannelTimer по этой идее:
Цитировать Пока что единственный выход (ИМХО) - создать один многоканальный таймер в котором каналы представляли бы собой обычные счетчики, значения в которых инкрементировались каждый раз при поступлении сигнала от этого таймера. При создании 10000 каналов оно также жрет ресурся ЦПУ, вдобавок еще и в консоль ничего не хочет выводить (но если создавать ~2000 каналов то выводит). myobject.h Код: #ifndef MYOBJECT_H main.cpp Код: #include <QtCore/QCoreApplication> Тестовый проектик прилагаю в аттач. Подскажите более правильное решение. :( Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: asvil от Декабрь 09, 2010, 00:05 Код: // GTK+ слот для обработки таймаута:) Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 08:36 Михаил , ну и какая у Вас получается загрузка CPU при (к примеру) 10000 каналов?
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: asvil от Декабрь 09, 2010, 10:19 Привожу полный код программы:
Код: #include <QtCore> Загрузка процесссора: 88% Занимаемое количество памяти: 30mb ubuntu linux amd athlon 2 x4 635 Я привел параметры из gnome-system-monitor Вывод, которого я дождался: Код: id 996477 timeout 153 Ну и слот, который будет не только qDebug делать, а еще много полезных вещей, также съест свою долю процессорного времени. Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: Igors от Декабрь 09, 2010, 10:47 А почему нельзя обойтись одним таймером: складывать запросы в сортированный (по времени) контейнер (напр QSet) и если обработка должна начаться скорее - подрезать интервал таймера
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 11:21 А почему нельзя обойтись одним таймером: складывать запросы в сортированный (по времени) контейнер (напр QSet) и если обработка должна начаться скорее - подрезать интервал таймера Код в студию.Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: asvil от Декабрь 09, 2010, 11:32 Хм, у меня один таймер используется. Скажите какие у вас средние таймауты?
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 12:55 В тему:
О ужас, посмотрел только что (бегло) исходники связанные с таймером под винду. И углядел, что на самом деле создается системный таймер с помощью Win32 API функции (MSDN): Цитировать UINT_PTR WINAPI SetTimer( При этом, чтобы создать таймер, функции необходим такой параметр как HWND hWnd, который является по сути дескриптором окна.__in_opt HWND hWnd, __in UINT_PTR nIDEvent, __in UINT uElapse, __in_opt TIMERPROC lpTimerFunc ); Воистину винда Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: BRE от Декабрь 09, 2010, 13:02 Венда это конечно жесть, но сейчас ты по моему ошибаешься. ;)
Одно окошко создается. Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 13:06 Упс, действительно одно. ::)
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 13:34 Еще по теме.
Интересно, а почему тролли/нокиа в исходниках Qt4 (по крайней мере 4.5.3) не используют для винды waitable-таймеры, для которых используются ф-ции: Цитировать CreateWaitableTimer SetWaitableTimer ... Это же было бы по идее лучше?! --- Думаю: может замутить нечто (класс-таймер) с использованием этих таймеров? Тем более, что при этом можно ловить события через QWinEventNotifier. ::) И проверить нагрузку на CPU. Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 14:27 Вот, сварганил по быстрому класс (для экспериментов):
myobject.h Код: #ifndef MYOBJECT_H main.cpp Код: #include <QtCore/QCoreApplication> В этом случае тоже запускаю ~10000 таймеров, при этом, нагрузка на процессор падает в ~5 раз, т.е. в данный момент в диспетчере задач около 10-12%. ЗЫ: Только при запуске оно ругается так: Цитировать ... QWinEventNotifier: Cannot have more than 62 enabled at one time ... К чему бы это? -- Ответ: это ограничение заложено в заголовках компилятора, а именно в winbase.h: Код: ... Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: Igors от Декабрь 09, 2010, 14:35 Свой вариант прилагаю, насчет загрузки - много зависит от платформы/железа, проще откомпилить и посмотреть
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: kuzulis от Декабрь 09, 2010, 15:48 Свой вариант прилагаю, насчет загрузки - много зависит от платформы/железа, проще откомпилить и посмотреть У меня при запуске твоего исходника всегда обрабатывается последний (один!) объект, а не все! :)В методе void CTestObject::Test( bool doPrint ) всегда выводится индекс последнего созданного объекта! Цитировать ... Это будет если сделать так к примеру:qDebug() << "object" << mIndex << "hit" << mNumHit << "interval" << theLastTime.msecsTo(tm); ... Код: ... Код: ... т.е. я хочу к примеру получать таймаут в 1 сек из трех объектов. Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: Igors от Декабрь 09, 2010, 17:20 Да, в этом случае ключ не уникален. Измените QMap на QMultiMap здесь
Код
Название: Re: QTimer или QBasicTimer или QObject::startTimer ? Отправлено: twp от Декабрь 10, 2010, 11:44 как вариант можно попробовать QElapsedTimer
|