for anyone who gets this same problem i managed to resolve the issue using two threads. The main program spawned a subprocess and used readlines to read the output. The process spawned was a script which executes a command using a thread. The thread reads the output from this command using readline. Within the main loop of the script there is a while loop which checks when the last output from the command was and if the time elapsed is greater than timeout the script prints to the stdout a string called timeout. In the main program the readline compares every output to see if it matches this sting. if it does kill process :) I'm sure this code could be implemented better but it works and got me out of a hole heres the thread script which contains the thread class and the time out loop: import datetime import time import threading import subprocess import os import sys class outputThread(threading.Thread): """ Thread is used to print the output of a command to the stdout """ def __init__(self,threadCommand, name="thread", *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.name = name self.killed = 0 self.counter = 0 self.command = threadCommand self.retval = None self.Set_Hit() def run(self): self.Proc = subprocess.Popen(self.command, cwd = os.getcwd(),stdin=subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) self.retval = None self.Set_Hit() while self.retval == None and not self.killed: line = self.Proc.stdout.readline() print line.rstrip("\r\n") sys.stdout.flush() self.Set_Hit() self.retval=self.Proc.poll() def Set_Hit(self): self.last_time = datetime.datetime.now() def Get_Hit(self): return self.last_time if __name__ == "__main__": """ This script is designed to put a timeout loop over a thread. The intention of this thread is to perform a command and have a timer loop over checking for the last text ouput from the command. If the loop exceeds the set time limit the command will stop reading the output from the thread """ command = [] timeout = 5 maxCounter = timeout curCounter = 0 strCounter = 0 if len(sys.argv) > 2: try: timeout = int(sys.argv[1]) except: print "time out value is not a float" sys.exit(1) for argPos in range(2,len(sys.argv)): print "arg = %s" % sys.argv[argPos] command.append(sys.argv[argPos]) else: print "not enough arguments" sys.exit(1) thread1 = outputThread(command,name="thread1") thread1.start() while True: if not thread1.retval == None: sys.exit(0) #Get current time and when timeout should occur currentTime = datetime.datetime.now() elapsedTime = thread1.Get_Hit() + datetime.timedelta(minutes=timeout) #Check Elapsed time if elapsedTime < currentTime: print "timed out" sys.stdout.flush() break time.sleep(1)
________________________________ From: Taylor, Stuart [mailto:[EMAIL PROTECTED] Sent: 13 March 2007 09:50 To: Sick Monkey; Taylor, Stuart Cc: python-list@python.org Subject: RE: Readline() i have a thread class which should read the output from the procedure line by line and finish when the thread is set to kill: class KillableThread(threading.Thread): def __init__(self, name="thread", *args, **kwargs): threading.Thread.__init__(self, *args, **kwargs) self.name = name self.killed = 0 def kill(self): self.killed = 1 def run(self): self.id = threading._get_ident() self.Proc = subprocess.Popen(["python","-tt","output_file.py"], cwd = os.getcwd(),stdin=subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) retval= None while retval == None and not self.killed: line = self.Proc.stdout.readline() retval=self.Proc.poll() to replicate my problem the output_file.py requires a user input. i ask for a user input as my thread will sit waiting on self.Proc.stdout.readline(). This is the point i want to have a timeout or be able to end my thread as there is no output from the output_file. The main approch i cannot implement is to be able to kill the thread as it remains hung on readlines() ________________________________ From: Sick Monkey [mailto:[EMAIL PROTECTED] Sent: 13 March 2007 01:51 To: Taylor, Stuart Cc: python-list@python.org Subject: Re: Readline() Maybe if you show us your code we can better assist you. But maybe you can use a global variable or a try-catch method to keep threads from staying alive and help better control your code. On 3/12/07, Taylor, Stuart <[EMAIL PROTECTED]> wrote: I have been working on running an external process using subprocess.popen for a few days. The process is ran over the network to another machine. One thing I have found is that if I perform readline() on the stdout it will hang if the process loses connection. I have tried a few things in a test example: one is to use stdin.write then stdin.flush() which send a string that readline() will read and it ends correctly but doesn't work on the project I need it to work on. Another is to try using threads and ignoar the thread when the process has lost connection but this still leaves the open thread alive even when the main app has finished. I am relatively new to python and I may be making a fundemantal mistake in my implementation, can anyone please inform me of whether sticking with subprocess.popen and readline() is the correct procedure for this sort of task? And if anyone can point me in the correct implementation of this problem I would be gratefull. Thank you Stuart -- http://mail.python.org/mailman/listinfo/python-list
-- http://mail.python.org/mailman/listinfo/python-list