我正在尝试使用以下算法检测系统暂停:
while True:
lastchecked = now()
if now() - lastchecked > 1s: print "suspend detected!"
但我遇到了一个问题:如果在第2行和第3行之间发生暂停,那么循环就会捕获它。但是如果在第1行和第2行之间发生挂起,则算法失败。
对于这种情况,是否有一些常用的方法?最好是OS独立的请,我不想挂钩OS事件等。
答案 0 :(得分:1)
首先,polling is inferiour to notifications因为它浪费了系统资源,而这些资源可以用在有用的工作上(而且你当前的循环也是busy loop)。当然,电源管理事件系统是特定于操作系统的(请参阅Power Management Notifications in Linux和how to hook to events / messages in windows using python),但如果您正在编写系统监控应用程序,则无论如何都无法隐藏操作系统差异。< / p>
现在,关键是在内存中总是有两个时间戳并覆盖旧的时间戳:
T1
\
T2
<- compare
/
T3
<- compare
\
T4
etc
/
然后,在暂停发生的任何时刻,下一个时间戳将设置得晚于它应该的时间,并且比较将看到差异。
这样,您甚至不需要每秒钟进行一次轮询!您的轮询间隔只需要与您要检测的最短暂停期间一样短。例如。如果您想要检测至少30秒的暂停期,您只需要每30秒轮询一次:如果系统睡眠时间更长,则可以保证&#34;错过节拍&#34;。
i=0
poll_period=30
t=[time.time()]*2
while True:
# actually, poll period will be slightly longer due to code overhead:
# https://stackoverflow.com/questions/26774186/looping-at-a-constant-rate-with-high-precision-for-signal-sampling
# but that doesn't make a difference in this case
time.sleep(poll_period)
t[i]=time.time()
if t[i] - t[(i+1)%2] > poll_period + 2: print "suspend detected"
i = (i+1)%2
请注意you will get false positives if your process gets preempted by others。这是使用系统通知的另一个原因,也是一种非常优越的方式。
答案 1 :(得分:0)
我认为这个算法有效:
last1 = now()
last2 = now()
while True:
last1 = now()
if now() - last1 > 1s or now() - last2 > 1s: print "suspend detected!"
last2 = now()
if now() - last1 > 1s or now() - last2 > 1s: print "suspend detected!"
这将在while循环中的任何行之后立即检测到挂起:
我认为这是检测系统挂起所需的最少代码量。如果我错了,请纠正我。