下面的代碼是借來的,並稍微「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進程的邏輯,用於提取終止的進程停止的地方等,但希望這應該能讓您瞭解如何繼續。
絕妙的回答!非常感謝你! – Dustin