2012-05-10 2 views
2

В настоящее время я работаю с модулем Python Spynner для автоматизации некоторых веб-задач. Я столкнулся с проблемой, хотя, по какой-то причине, процесс просто прекратил бы движение, замерзнул, но все же будет реагировать в соответствии с Windows.Мониторинг сбоя программы

Что бы я хотел сделать, это установить какую-либо форму монитора для проверки и посмотреть, произойдет ли это, а затем перезапустите процесс. Я думал о возможности мониторинга вывода терминала в программе, и если он перестанет толкать данные через определенное время, он убьет программу и снова запустится.

Я знаю, как я хотел бы убить программу и запустить ее снова, просто используя os и subprocess, но я не уверен, как настроить кусок, чтобы отслеживать, прекращает ли терминал отправлять данные за определенное количество время.

ответ

5

Следующий код заимствован и слегка изменен с «Non-blocking read on a subprocess.PIPE in python» (престижность JF Sebastian - если вы принимаете этот ответ, пожалуйста, upvote исходный код)

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, чтобы забрать, где прекращено одно прекращение и т. д., но, надеюсь, это должно дать вам представление о том, как действовать.

+0

Блестящий ответ! Большое спасибо! – Dustin

Смежные вопросы