2012-05-10 86 views
2

我目前正在使用Python模塊Spynner來自動執行一些Web任務。我遇到了一個問題,雖然由於某種原因,這個過程只是停止移動,凍結,但仍然響應Windows。監視程序崩潰

我想要做的是設置某種形式的監視器來檢查並查看是否發生這種情況,然後重新啓動該過程。我正在考慮可能監視程序的終端輸出,並且如果它在一段時間後停止推送數據,它會終止程序並重新啓動。

我知道我是如何殺死程序並再次運行它,只是使用操作系統和子進程,但我不知道如何設置一塊監視,如果終端停止發送數據的特定數量時間。

回答

5

下面的代碼是借來的,並稍微「Non-blocking read on a subprocess.PIPE in python」修改(榮譽給JF塞巴斯蒂安 - 如果你接受這個答案,請給予好評原碼)

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