這篇文章
中說過qt程序使用qtimer的靜態signalshot函式會建立單次觸發的定時器.建立後,該定時器沒到觸發時間是無法析構的.如果建立該定時器的物件析構,該定時器會洩漏到被觸發為止.所以使用signalshot
的話隨著時間推移,積累的定時器可能會越來越多.出現莫名奇妙的錯誤.只有終端中會出現這個提示(如果是ui程式沒終端就更懵逼了).
qeventdispatcherwin32::registertimer: failed to create a timer (當前程式已使用了 window 管理器物件的系統允許的所有控制代碼。
之前一直以為真的是qtimer洩漏導致控制代碼數量達到了上限.所以將所有的signalshot都改為可銷毀的qtimer後,依然偶爾會出現這個提示.經過研究發現是被這個提示誤導了.並不是控制代碼達到了上限,而是使用者物件數量達到了上限.windows每個程序最多只能建立10000個使用者物件.每個活動的qtimer要使用乙個windows的timer(使用者物件).當程序管理的物件需要大量定時器(超過10000 - 其他地方使用的使用者物件數量)時,就會出現上述錯誤.並且該定時器既無法被觸發,也不會停止.進入一種沒有辦法直接捕獲的錯誤狀態.並且該進場無法正確的建立所有需要使用windows使用者物件的物件.
我們程式可能真的需要大量定時器,並且這些定時器都會長時間保持執行狀態(占用windows使用者物件)怎麼辦呢?只能自己實現了.
這類大數量的定時器通常都有觸發週期很長,精度要求很低的特點.根據這個特點.我寫了乙個可以替代qtimer並且不占用windows使用者物件的定時器mytimer.
這個timer最好狀態精度能夠達到毫秒,最差理論延時可能達到1秒.對於要求精度不高的場合,可以替代qtimer,防止windows使用者物件數量報表
這個timer使用了我自己的單例模式和物件集合.
標頭檔案
#ifndef mytimer_h
#define mytimer_h
#include #include "gather/gather.h"
#include "singleton/singleton.h"
#include #include #define latter(x) qmetaobject::invokemethod(this, x, qt::queuedconnection)
class mytimerdriver;
class mytimer : public qobject, public gather
void start(int msec)
void start()
void stop()
void setinterval(int msec)
void setsingleshot(bool singleshot)
signals:
void timeout();
private:
qint64 triggertime_;
bool singleshot_;
int interval_;
//driver通過checktimers來重新整理定時器.driver通過checktimers來重新整理定時器會依次重新整理各個定時器的checktimer
//每次有最大觸發數量.讓1s內觸發的定時器均勻的觸發在每毫秒
bool checktimer();
static mytimerdriver* driver;
static void checktimers();
friend class mytimerdriver;
};class mytimerdriver : public qthread
;#endif // mytimer_h
實現
#include "mytimer.h"
#include mytimerdriver* mytimer::driver = null;
mytimer::mytimer(qobject *parent) :
qobject(parent)
triggertime_ = -1;
singleshot_ = false;
interval_ = 1;
}bool mytimer::checktimer()
emit timeout();
trigged = true;}}
return trigged;
}void mytimer::checktimers()}}
}mytimerdriver::mytimerdriver()
void mytimerdriver::run()
}void mytimerdriver::checktimer()
使用乙個每天觸發的定時器
mytimer
connecting_
; connecting_.setinterval(24 * 60 * 60 * 1000);
connecting_.setsingleshot(false);
qobject::connect(&connecting_, signal(timeout()), this, slot(deletelater()));
connecting_.start();
C 的引用型別的變數到底佔不占用記憶體空間?
分析一下 c 裡面的引用型別 例如 int r a 中的r變數是否占用記憶體空間呢?是否和 int p a 中的p變數一樣占用記憶體空間呢?本文將給出答案。直接看乙個簡單的例子 include using namespace std int main void 接著我們通過 g testref.cp...
windows檢視埠占用的命令
大家知道在linux下使用 lsof p 埠號 可以檢視埠的程序 使用此命令可以檢視win下所有開著的埠是被那個系統程式占用以及程式的pid。n年前搞測試的時候解決埠占用問題時候用的命令,想裡半天才回憶出來。分享給大家。為了方便記憶引數寫成了no ab 更多引數請查考netstat 一下是節選部分輸...
Windows使用者的分類
根據是否享有聯機服務分為 微軟使用者,本地使用者 根據許可權分為 超級管理員使用者 即系統內建的administrator賬戶 普通管理員使用者 使用者自己設定的管理員賬戶,許可權跟administrator相同,但需要通過uac視窗進行確認 普通使用者 無管理員許可權賬戶 需要注意的是上面按照許可...