Readline()

Taylor, Stuart Stuart.Taylor at disney.com
Fri Mar 16 11:27:48 CET 2007


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:Stuart.Taylor at disney.com] 
Sent: 13 March 2007 09:50
To: Sick Monkey; Taylor, Stuart
Cc: python-list at 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:sickcodemonkey at gmail.com] 
Sent: 13 March 2007 01:51
To: Taylor, Stuart
Cc: python-list at 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 <Stuart.Taylor at disney.com> 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
	


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20070316/6866cc8f/attachment.html>


More information about the Python-list mailing list