【问题标题】:Monitoring for Program Crash监控程序崩溃
【发布时间】:2012-05-18 15:05:00
【问题描述】:

我目前正在使用 Python 模块 Spynner 来自动执行一些网络任务。我遇到了一个问题,但由于某种原因,该进程只是简单地停止移动、冻结,但仍然根据 Windows 做出响应。

我想做的是设置某种形式的监视器来检查是否发生这种情况,然后重新启动该过程。我在想可能会监控程序的终端输出,如果它在一定时间后停止推送数据,它会杀死程序并重新启动。

我知道我想如何杀死程序并再次运行它,只需使用 os 和子进程,但我不确定如何设置该程序以监视终端是否在特定时间内停止发送数据.

【问题讨论】:

    标签: python crash subprocess spynner


    【解决方案1】:

    以下代码是从“Non-blocking read on a subprocess.PIPE in python”借用并稍作修改的(感谢 J.F. Sebastian - 如果您接受此答案,请为原始代码投票)

    import sys
    import time
    from subprocess import PIPE, Popen
    from threading  import Thread
    
    try:
        from Queue import Queue, Empty
    except ImportError:
        from queue import Queue, Empty  # python 3.x
    
    ON_POSIX = 'posix' in sys.builtin_module_names
    
    def enqueue_output(out, queue):
        for line in iter(out.readline, b''):
            timestamp = time.time( )
            queue.put((timestamp, line))
        out.close()
    
    #-- This is how long you're willing to wait before you 
    #-- consider your Spynner process to be brain-dead.
    MAX_WAIT_TIME = 300.0  #-- we'll wait 5 minutes (300 seconds)
    
    #-- Construct a shared queue that will be used to send messages from 
    #-- the subprocess I/O polling thread to the watchdog (main) thread.
    q = Queue()
    
    #-- Spawn your subprocess...
    p = Popen(['myprogram.exe'], stdout=PIPE, bufsize=1, close_fds=ON_POSIX)
    
    #-- Create a new thread that runs in the same process as the watchdog.
    #-- This thread will poll the output of the subprocess and populate the 
    #-- shared queue.
    t = Thread(target=enqueue_output, args=(p.stdout, q))
    t.daemon = True # thread dies with the program
    t.start()
    
    #-- Now, we'll try to read from the shared queue.
    try:
        #-- Queries the shared queue for the next item in the queue,
        #-- waiting for up to MAX_WAIT_TIME before failing with an Empty exception.
        timestamp, line = q.get(True, MAX_WAIT_TIME)
    except Empty:
        #-- Ok...the queue is empty and it's been MAX_WAIT_TIME since
        #-- We've pulled anything from the queue.
        p.terminate( )  #-- "terminate with extreme prejudice"
    else: # got line
        #-- Got a (timestamp, line_of_text) pair, where the timestamp is the
        #-- system time when the I/O polling thread grabbed the line from
        #-- the subprocess pipe.  This timestamp isn't strictly necessary,
        #-- but might come in handy in debugging the brain-dead Spynner process.
        #-- So now...do something with that line of text!
        doSomething(line)
    

    您必须使用一些逻辑来扩充此代码,以生成一个新的 Spynner 进程以从终止的进程停止的地方继续,等等,但希望这能让您了解如何继续。

    【讨论】:

    • 绝妙的答案!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-23
    • 1970-01-01
    • 2020-03-27
    • 2014-03-05
    相关资源
    最近更新 更多