在x秒不活动后退出python脚本

时间:2015-04-13 11:29:04

标签: python timer raspberry-pi exit

我有一个覆盆子pi的脚本,它不断读取数据并将数据保存到文件中。但是我知道这很危险,因为如果在保存数据的同时拉动电源会导致SD卡损坏。

如果计算机在一段时间内处于非活动状态,是否可以让脚本自行终止?

很抱歉,如果这个问题含糊不清,但我不知道从哪里开始,所以我无法显示我尝试过的任何代码。

4 个答案:

答案 0 :(得分:1)

这是一个天真的看门狗实施:

import os
import signal
import threading



class Watchdog():
    def __init__(self, timeout=10):
        self.timeout = timeout
        self._t = None

    def do_expire(self):
        os.kill(os.getpid(),signal.SIGKILL)

    def _expire(self):
        print("\nWatchdog expire")
        self.do_expire()

    def start(self):
        if self._t is None:
            self._t = threading.Timer(self.timeout, self._expire)
            self._t.start()

    def stop(self):
        if self._t is not None:
            self._t.cancel()
            self._t = None

    def refresh(self):
        if self._t is not None:
             self.stop()
             self.start()

wd = Watchdog()构建,每当您收到满足工作要求的内容wd.refresh()时。如果您在超时结束前没有调用刷新,则会调用os.kill(os.getpid(),signal.SIGKILL)

您不能仅使用sys.exit(),因为它只引发SystemExit例外:使用kill可以根据需要使用。

现在您可以使用某些内容来轮询系统并使用答案刷新或不看门狗。例如xprintidle告诉你X空闲时间,但都取决于你需要监控的时间。

使用示例

timeout=10
wd = Watchdog(timeout)
wd.start()
while True:
    a=str(raw_input('Tell me something or I will die in {} seconds: '.format(timeout)))
    wd.refresh()
    print("You wrote '{}'... you win an other cycle".format(a[:-1))

答案 1 :(得分:1)

xprintidle实用程序,可以使这个任务变得简单:

#!/usr/bin/env python
# encoding: utf-8

import subprocess as sp
import threading
import time
import sys

def quit_on_idle(threshold=2000):
    import thread
    # note that sys.stdout.write and .flush should rather be used
    # instead of print
    while True:
        try:
            idle = float(sp.check_output('xprintidle').strip())
            if idle > threshold:
                print 'Inactive for {} seconds'.format(idle / 1000)
                break
        except (ValueError, sp.CalledProcessError) as err:
            print 'An error occured'
            # add your error handling here
        time.sleep(0.2)
    thread.interrupt_main()

try:
    threading.Thread(target=quit_on_idle).start()
    print 'Watchdog has been started in a separate thread'
    time.sleep(1)
    print 'one second passed'
    time.sleep(3)
    print 'This may not run at all, if you left computer idle'
except KeyboardInterrupt:
    print 'Bye'

答案 2 :(得分:0)

我为xthon包装了xprintidle,我很想知道它是否符合你的要求!

https://pypi.python.org/pypi/xprintidle

安装:

pip install xprintidle

使用:

import xprintidle
print xprintidle.idle_time()

让我知道你怎么走:)。

答案 3 :(得分:0)

您可以调用libXss.XScreenSaverQueryInfo()函数来获取空闲时间,就像屏幕保护程序在X中一样。纯Python pxss.py显示了如何完成它。下载它并将其放在您的代码旁边:

#!/usr/bin/env python
from __future__ import division
import os
import signal
import time

# $ wget https://raw.githubusercontent.com/mariano/snakefire/9437e59ffe9deff83676c5101a0dbf694ad3344b/snakefire/pxss.py
import pxss

def watchdog(timeout, idle_callback):
    """Call *idle_callback* after *timeout* seconds of inactivity."""
    tracker = pxss.IdleTracker(idle_threshold=timeout*1000)
    while True:
        state_change, wait_time, _ = tracker.check_idle()
        if state_change == "idle":
            idle_callback()
        time.sleep(wait_time / 1000)

def die():
    """thread.interrupt_main() analog."""
    os.kill(os.getpid(), signal.SIGINT)

示例:

import sys
import threading
from itertools import cycle

# exit after 10 seconds of inactivity
t = threading.Thread(target=watchdog, args=[10, die])
t.daemon = True
t.start()

# do whatever you like here that can be interrupted by Ctrl+C
try:
    for c in cycle('/|\-'):
        sys.stderr.write('\b' + c)
        sys.stderr.flush()
        time.sleep(.2)
except KeyboardInterrupt:
    print('bye')