여러 응용 프로그램에서 동시에 열 수있는 리소스 (클래스) 인스턴스에 유휴 타이머를 구현했습니다. 따라서 idleTimer
은 단순한 QTimer
일뿐 아니라 슬롯 (트리거)은 다른 N 응용 프로그램이 마지막 N 분 동안 동일한 리소스에 액세스하지 않았는지 확인해야합니다. 이 경우 타이머가 재설정되고 (lastAccessedTime
값을 업데이트하지 않음) 그렇지 않으면 자원이 닫힙니다. 따라서 타이머는 단일 셀이며 lastAccessTime
은 QSharedMemory 객체에 보관됩니다.OS X의 빠른 QTimer가 여러 번 빠르게 실행되었습니다.
는 여기에 몇 가지 추적 출력입니다 :
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83601 timer QTimer(0x11d273d60) triggered 1 times
### slotIdleTimedOut ->handleIdleTiming: setting QTimer(0x11d273d60) for wallet "kdewallet" handle 0 timeout to 6
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 2 times
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 3 times
### "Google Contacts()of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 4 times
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83634 timer QTimer(0x11d273d60) triggered 5 times
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 6 times
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 7 times
### "Google Contacts() of type Google Contacts" Idle timeout 6 min. for KWallet::Wallet(0x105d1f900) "kdewallet" handle 0 ; elapsed minutes= 5.83635 timer QTimer(0x11d273d60) triggered 8 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle 0 ; elapsed minutes= 6 timer QTimer(0x120a1b5f0) triggered 1 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00008 timer QObject(0x0) triggered 2 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00009 timer QObject(0x0) triggered 3 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 4 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 5 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 6 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 7 times
### "KMail" Idle timeout 6 min. for KWallet::Wallet(0x1083f1ac0) "kdewallet" handle -1 ; elapsed minutes= 6.00012 timer QObject(0x0) triggered 8 times
원리 작품,하지만 난 2 가지주의 사항 :
- 타이머가 조금 일찍 발생합니다. 물론 타이머가 재설정됩니다.
- 빠른 연속으로 여러 번 발사됩니다. 조기 화재로 리셋해야만한다는 사실은 그다지 효과가 없습니다.
다음은 각 리소스 액세스시 타이머를 다시 설정하는 기능과 타이머의 트리거 슬롯을 비롯한 내 코드의 관련 부분입니다.
내가 뭘 잘못하고 있는지 아는 사람이 있습니까? 타이머를 멈추고 (다시) singleshot 모드로 설정하고 다시 시작합니다 (새로). 객체 및 응용 프로그램 식별자는 실제로 여러 번 트리거하는 동일한 타이머이며, 타이머 객체를 삭제 한 후에도 트리거 될 수 있음을 보여줍니다.
트리거 슬롯이이 타이머의 인스턴스를 설정하는 다양한 응용 프로그램의 다른 모든 인스턴스로부터 idleTimer
트리거 신호를 수신하는 1 인스턴스로 연결되는 응용 프로그램 (또는 심지어 인스턴스)과 관련이 없습니까? idleTimer
은 클래스 소멸자에서만 NULL로 설정되거나 timeOut
이 < = 0 일 때 NULL 타이머 객체로 호출 될 수 있습니다. 타이머에서
설치
기능 (handleIdleTiming
이
KWallet::Wallet
의 회원이
idleTimer
자체로) :
// This function is to be called at every operation that is supposed to launch or reset
// the idle timing. @p timeOut is a time in minutes.
void handleIdleTiming(const char *caller="", bool touchAccessTime=true)
{
// ...
if(timeOut >= 0){
if(!idleTimer){
idleTimer = new QTimer(0);
}
else{
idleTimer->stop();
}
// when the idle timer fires, the wallet is supposed to be closed. There is thus
// no reason to use a repeating timer.
idleTimer->setSingleShot(true);
connect(idleTimer, SIGNAL(timeout()), q, SLOT(slotIdleTimedOut()));
if(touchAccessTime){
if(lastAccessTime.lock()){
*((double*)lastAccessTime.data()) = HRTime_Time();
lastAccessTime.unlock();
}
else{
qDebug() << "Cannot lock lastAccessTime for wallet" << name << "error" << lastAccessTime.errorString();
}
}
idleTimer->start(timeOut * 60 * 1000);
타이머 트리거 슬롯 :
void Wallet::slotIdleTimedOut()
{ double lastAccessTime = 0;
// check the last time anyone accessed this wallet:
if(d->lastAccessTime.lock()){
lastAccessTime = *((double*)d->lastAccessTime.data());
d->lastAccessTime.unlock();
}
else{
qDebug() << "Cannot lock lastAccessTime for wallet" << d->name << "error" << d->lastAccessTime.errorString();
}
// the time elapsed since that last access, in minutes:
double elapsed = (HRTime_Time() - lastAccessTime)/60;
d->idleTimerTriggered += 1;
qDebug() << "###" << appid() << "Idle timeout" << d->timeOut << "min. for" << this << d->name << "handle" << d->handle
<< "; elapsed minutes=" << elapsed << "timer" << d->idleTimer << "triggered" << d->idleTimerTriggered << "times";
if(elapsed >= d->timeOut){
// we have a true timeout, i.e. we didn't access the wallet in timeOut minutes, and no one else did either.
slotWalletClosed(d->handle);
}
else{
// false alarm, reset the timer, but there's no need to count this as an access!
d->handleIdleTiming(__FUNCTION__, false);
}
}
'new QTimer (0)'다음에 한 번만 쓰는 대신 connect() (잠재적으로)를 반복적으로 호출하기 때문에 이것이 가능합니까? – RJVB