Cleanly end a thread with blocked i/o in win32?

Elbert Lev elbertlev at hotmail.com
Fri Oct 22 04:06:00 CEST 2004


jonathan.wright at gmail.com (Jon Wright) wrote in message news:<56b071ab.0410211035.440de0ef at posting.google.com>...
> Trying to work around the lack of pexpect for native windows python I
> had a play with os.popen2 and some threads. This looks promising
> enough for what I want to do, but I hit on a problem with getting the
> script to exit cleanly. Tried replacing popen with subprocess but I am
> still confused. Either it needs to be killed from the task manager, or
> I get a variety of different complaints and popping up "application
> error" windows. I managed to get it to stop with os.abort(), but this
> invites a complaint from windows about terminating in an unusual way.
> Closing the file descriptors of the child process leads to a crash and
> I think I should be sending a kill to the process, although I don't
> know how (please tell me).
> 
> Would any of you care to have a look at the code below and make
> suggestions for tidying it up properly? It also dies nastily if the
> child process terminates. Eventually I would like to fire off a
> program from a gui, supply input programmatically, depending upon the
> unpredicable questions the program might ask, and prompt the user if
> the child process asks something unknown. Also process the output into
> a graphical form so the user can change options and run the child
> again. Makes the crashing a bit of a problem! Entirely different
> approaches which can accomplish this task would also be very very
> welcome, I tried a telnet to localhost suggestion, but this was
> painfully slow on this windows xp machine (using "services for unix"
> telnet server). The communicate bit of subprocess only gives me one
> chance to talk to the process. Should I be inheriting from subprocess
> and editing the communicate method there?
> 
> Having googled extensively on this problem it seems that tidying up
> this code could be useful to others too?
> 
> Thanks!!
> 
> Jon
> ---
> import os,sys,time,subprocess
> from threading import Thread
> 
> out = ""  
> 
> class reader(Thread):
>    def __init__(self,file_to_read):
>       self.file_to_read=file_to_read
>       Thread.__init__(self)
>    def run(self):
>       global out
>       while 1:
>          i=self.file_to_read.read(1)
>          out+=i 
>          sys.stdout.write(i) # for debugging
> 
> class writer(Thread):
>    def __init__(self,file_to_write):
>       self.file_to_write=file_to_write
>       Thread.__init__(self)
>    def run(self):
>       global out
>       while 1:
>          i=sys.stdin.read(1) # for debugging 
>          out+=i 
>          self.file_to_write.write(i) 
> 
> if __name__=="__main__":
>    child = subprocess.Popen(sys.argv[1],
>                             stdin=subprocess.PIPE,
>                             stdout=subprocess.PIPE) 
>    # or: child.stdout,child.stdin = os.popen2(sys.argv[1])
>    r = reader(child.stdout)
>    w = writer(child.stdin)
>    r.start()
>    w.start()
>    while r.isAlive() and w.isAlive():
>        try:
>           time.sleep(10)
>        except:
>           print "\n=== in out now ===\n",out,"\n======"
>           break
>    print r.isAlive(),w.isAlive() # Who died, in or out??
>    time.sleep(1)
>    print r.isAlive(),w.isAlive() # Who died, in or out??
>    print "You fell off of the bottom of the script"

Just curiosity: why did you try using UNIX methods in win32?
To prove that windows isn't unix?



More information about the Python-list mailing list