Cleanly end a thread with blocked i/o in win32?
Elbert Lev
elbertlev at hotmail.com
Thu Oct 21 22:06:00 EDT 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