python - 检测系统在循环中挂起
问题描述
我正在尝试使用以下算法检测系统挂起:
while True:
lastchecked = now()
if now() - lastchecked > 1s: print "suspend detected!"
但是我遇到了一个问题:如果挂起发生在第 2 行和第 3 行之间,那么循环会捕获它。但是如果挂起发生在第一行和第二行之间,那么算法就会失败。
这种情况有一些常用的方法吗?最好是独立于操作系统的,我不想挂钩操作系统事件等。
解决方案
首先,轮询不如通知,因为它浪费了系统资源,而这些资源可以花在有用的工作上(而且您当前的循环也是一个繁忙的循环)。自然,电源管理事件系统是特定于操作系统的(请参阅Linux 中的电源管理通知以及如何使用 python 连接到 Windows 中的事件/消息),但是如果您正在编写系统监视器应用程序,则无论如何您都无法隐藏操作系统差异.
现在,这里的关键是在内存中始终有两个时间戳并覆盖旧的:
T1
\
T2
<- compare
/
T3
<- compare
\
T4
etc
/
然后,无论何时发生挂起,下一个时间戳都将设置得比它应该设置的晚,并且比较会看到差异。
这样,您甚至不需要每秒钟左右轮询一次!您的轮询间隔只需与您想要检测的最短暂停时间一样短。例如,如果您想检测至少 30 秒的暂停时间,您只需每 30 秒轮询一次:如果系统睡眠时间更长,则可以保证“错过一个节拍”。
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
请注意,如果您的进程被其他人抢占,您将得到误报。这就是为什么使用系统通知是一种非常优越的方式的另一个原因。
推荐阅读
- python - Python Turtle Graphics Tic - Tac - 脚趾游戏
- python - PyCon 2012 David Mertz 谈协程作为线程
- java - 长度可变的数组
- python - 反正有实时的DHT22数据吗?
- java - 如何从firebase中检索键和值并将它们存储在两个单独的变量中
- php - 有没有办法将数组元素添加到 SESSION 变量中?
- xamarin.forms - FreshPageModelResolver.ResolvePageModel() 在 UWP Release 中抛出异常
- hbase - Hbase 区域始终处于过渡状态
- asp.net-mvc - 查询多张表(二)
- functional-programming - 在 Scheme 的这种应用减少中,“let”来自哪里?