#ifndef MYOBJECT_H#define MYOBJECT_H#include <QtCore/QTimerEvent>#include <QtCore/QDebug>#include <QtCore/QObject>class MyObject : public QObject{ Q_OBJECTpublic: explicit MyObject(QObject *parent = 0) : QObject(parent) { this->startTimer(1); }protected: void timerEvent(QTimerEvent *event) { qDebug() << "Timer ID:" << event->timerId(); }};#endif // MYOBJECT_H
#include <QtCore/QCoreApplication>#include "myobject.h"int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); int counter = 10000; while (counter--) new MyObject(); return a.exec();}
#ifndef MYOBJECT_H#define MYOBJECT_H#include <QtCore/QTimerEvent>#include <QtCore/QMap>#include <QtCore/QDebug>#include <QtCore/QObject>class MultiChannelTimer : public QObject{ Q_OBJECTsignals: void timeout(int);public: explicit MultiChannelTimer(QObject *parent = 0) : QObject(parent), timerId(0) { connect(this, SIGNAL(timeout(int)), this, SLOT(result(int))); } ~MultiChannelTimer() { if (this->timerId) this->killTimer(this->timerId); qDeleteAll(this->map); } int createChannel(bool autoReset = true) { TimerChannel *ch = new TimerChannel(this->freeId()); ch->autoreset = autoReset; this->map.insert(ch->id, ch); return ch->id; } void deleteChannel(int channelId) { TimerChannel *ch = this->map.take(channelId); if (ch) delete ch; } void startChannel(int channelId, int msecs) { if (!this->timerId) this->timerId = this->startTimer(10); if (!this->timerId) return; TimerChannel *ch = this->channel(channelId); if (ch) { ch->currCounterValue = msecs; ch->constCounterValue = msecs; ch->started = true; } } void stopChannel(int channelId) { TimerChannel *ch = this->channel(channelId); if (ch) ch->started = false; } bool isStarted(int channelId) const { TimerChannel *ch = this->channel(channelId); return (ch) ? ch->started : false; }protected: void timerEvent(QTimerEvent *event) { if (event->timerId() == this->timerId) { foreach (TimerChannel *ch, this->map) { if (ch && ch->started) { if ((ch->currCounterValue--) < 0) { if (ch->autoreset) ch->currCounterValue = ch->constCounterValue; emit timeout(ch->id); } } } } }private: class TimerChannel { public: TimerChannel(int id) : id(id) , currCounterValue(0) , constCounterValue(0) , autoreset(false) , started(false) {} int id; int currCounterValue; int constCounterValue; bool autoreset; bool started; }; TimerChannel *channel(int channelId) const { return this->map.value(channelId, 0); } int freeId() const { int id = 0; QList<int> list = this->map.keys(); while (list.contains(id)) { ++id; } return id; } int timerId; QMap<int, TimerChannel *> map;private slots: void result(int id) { qDebug() << "Id: " << id; }};#endif // MYOBJECT_H
#include <QtCore/QCoreApplication>#include "myobject.h"int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); MultiChannelTimer mct; int id = 0; int count = 10000; while (count--) { id = mct.createChannel(); mct.startChannel(id, 5); } return a.exec();}
// GTK+ слот для обработки таймаута:)typedef void (*timeout)(quint64);// односвязный список таймеровtypedef struct timers { quint64 id; int timeout; struct timers* next;}//точность таймера#define precision 10 class Channel : public QObject{ Q_OBJECT quint64 idgenerator; // переменная для генерации идентификаторов таймеров timers *first; // указатель на односвязный список таймеров timeout callback;public: Channel(QObject* parent = 0) { idgenerator = 0; first = 0; startTimer(precision); // Ваша точность 10 msec } virtual ~Channel(); // return timer id quint64 addTimer(int timeout) { timers* that = malloc(sizeof(struct timers)); that->id = idgenerator++; that->timeout = timeout; that->next = first; first = that; return that->id; } void setTimeoutSlot(timeout slot) { callback = slot; }protected: void timerEvent(QTimerEvent *event) { timers *next = first; timers *previous = 0; while (next) { --next->timeout; if (!next->timeout) { if (previous) { previous->next = next->next; } else { first = next->next; } callback(next->id); free(next); } previous = next; next = next->next; } }};void fancytimeout(quint64 id){ qDebug() << id << "timeout";}void main(int argc, char** argv) { QCoreApplication app(argc, argv); Channel channel; channel.setTimeoutSlot(fancytimeout); // Наполняем таймерами for (int i = 0; i < MAX_INT; ++i) channel.addTimer(qRand()/precision); // qRand() - кол-во msec app.exec();}
#include <QtCore>#include <QCoreApplication>// GTK+ слот для обработки таймаута:)typedef void (*timeout)(quint64, int);// односвязный список таймеровstruct timers { quint64 id; int timeout; int elapsed; struct timers* next;};//точность таймера#define precision 10class Channel : public QObject{ quint64 idgenerator; // переменная для генерации идентификаторов таймеров timers *first; // указатель на односвязный список таймеров timeout callback;public: Channel(QObject* parent = 0) :QObject(parent){ idgenerator = 0; first = 0; startTimer(precision); // Ваша точность 10 msec } virtual ~Channel(){ } // return timer id quint64 addTimer(int timeout) { timers* that = (timers*)malloc(sizeof(struct timers)); that->id = idgenerator++; that->timeout = timeout; that->elapsed = timeout; that->next = first; first = that; return that->id; } void setTimeoutSlot(timeout slot) { callback = slot; }protected: void timerEvent(QTimerEvent *event) { timers *next = first; timers *previous = 0; while (next) { --next->timeout; if (!next->timeout) { if (previous) { previous->next = next->next; } else { first = next->next; } callback(next->id, next->elapsed); free(next); } previous = next; next = next->next; } }};void fancytimeout(quint64 id, int elapsed){ qDebug() << "id" << id << "timeout" << elapsed;}int main(int argc, char** argv) { QCoreApplication app(argc, argv); Channel channel; channel.setTimeoutSlot(fancytimeout); sleep(5); // Наполняем таймерами for (int i = 0; i < 1000000; ++i) channel.addTimer(qrand()/precision); // qRand() - кол-во msec sleep(5); return app.exec();}
id 996477 timeout 153 id 891698 timeout 507 id 500001 timeout 528 id 99268 timeout 1406 id 583055 timeout 1519 id 562457 timeout 1638 id 216986 timeout 1836 id 411259 timeout 2229 id 892895 timeout 2341 id 16990 timeout 2669 id 297043 timeout 2823 id 176393 timeout 2850 id 12546 timeout 3165 id 734402 timeout 3341 id 252614 timeout 3394 id 976756 timeout 3445 id 487864 timeout 3767 id 309831 timeout 3933 id 589093 timeout 3955 id 321155 timeout 4210 id 174007 timeout 4342 id 673380 timeout 4609
#ifndef MYOBJECT_H#define MYOBJECT_H#include <QtCore/QObject>#include <QtCore/private/qwineventnotifier_p.h>#include <QtCore/QEvent>#include <QtCore/QDebug>#include <qt_windows.h>class WaitableTimer : public QWinEventNotifier{ Q_OBJECTsignals: void timeout();public: explicit WaitableTimer(QObject *parent = 0) : QWinEventNotifier(parent) { this->hTimer = ::CreateWaitableTimer(0, 0, 0); } ~WaitableTimer() { this->setEnabled(false); if (this->stop()) ::CloseHandle(this->hTimer); } bool start(int msecs) { ::LARGE_INTEGER liDueTime; memset(&liDueTime, 0, sizeof(::LARGE_INTEGER)); bool ret = (0 != ::SetWaitableTimer(this->hTimer, &liDueTime, ::LONG(msecs), 0, 0, 0)); if (ret) { this->setHandle(this->hTimer); this->setEnabled(true); } return ret; } bool stop() { return (0 != ::CancelWaitableTimer(this->hTimer)); }protected: bool event(QEvent *e) { bool ret = false; if (e->type() == QEvent::WinEventAct) qDebug() << "TimerHandle: " << this->hTimer; else ret = QWinEventNotifier::event(e); return ret; }private: ::HANDLE hTimer;};#endif // MYOBJECT_H
#include <QtCore/QCoreApplication>#include "myobject.h"int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); int count = 10000; while (count--) { WaitableTimer *wt = new WaitableTimer; wt->start(10); } return a.exec();}
...#define MAXIMUM_WAIT_OBJECTS 64...