检测系统在循环中暂停

时间:2018-06-10 16:07:05

标签: python algorithm

我正在尝试使用以下算法检测系统暂停:

while True:
    lastchecked = now()
    if now() - lastchecked > 1s: print "suspend detected!"

但我遇到了一个问题:如果在第2行和第3行之间发生暂停,那么循环就会捕获它。但是如果在第1行和第2行之间发生挂起,则算法失败。

对于这种情况,是否有一些常用的方法?最好是OS独立的请,我不想挂钩OS事件等。

2 个答案:

答案 0 :(得分:1)

首先,polling is inferiour to notifications因为它浪费了系统资源,而这些资源可以用在有用的工作上(而且你当前的循环也是busy loop)。当然,电源管理事件系统是特定于操作系统的(请参阅Power Management Notifications in Linuxhow 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循环中的任何行之后立即检测到挂起:

  • 第二行将被第二行检测到暂停(因为last1将是旧的)。
  • 第4行将被第4行检测到暂停(因为last1将是旧的)。
  • 第4行将被第4行检测到暂停(因为last1和last2都将是旧的)。
  • 第2行将被第2行检测到暂停(因为last2将是旧的)。

我认为这是检测系统挂起所需的最少代码量。如果我错了,请纠正我。