不占用windows使用者物件的定時器

2021-07-24 12:46:40 字數 2622 閱讀 2813

這篇文章

中說過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視窗進行確認 普通使用者 無管理員許可權賬戶 需要注意的是上面按照許可...