Is there a way to make a subprocess call in python "persistent"? I'm calling a program that takes a while to load multiple times. So it would be great if I could just leave that program open and communicate with it without killing it.
The cartoon version of my python script looks like this:
for text in textcollection:
myprocess = subprocess.Popen(["myexecutable"],
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = None)
myoutputtext, err = myprocess.communicate(input=text)
I need to process each text separately, so joining it all into one large text file and processing it once is not an option.
Preferably, if there's an option like this
myprocess = subprocess.Popen(["myexecutable"],
stdin = subprocess.PIPE, stdout = subprocess.PIPE,
stderr = None) for text in textcollection:
for text in textcollection:
myoutputtext, err = myprocess.communicate(input=text)
where I can leave the process open, I'd really appreciate it.
You can use
myprocess.stdin.write()
andmyprocess.stdout.read()
to communicate with your subprocess, you just need to be careful to make sure you handle buffering correctly to prevent your calls from blocking.If the output from your subprocess is well-defined, you should be able to reliably communicate with it using line-buffering and
myprocess.stdout.readline()
.Here is an example:
An alternative to this method for Unix is to put the file handle in non-blocking mode, which will allow you to call functions like
myprocess.stdout.read()
and have it return data if any is available, or raise anIOError
if there isn't any data:This would allow you to do something like this:
In this example,
validate_output()
is a function you would need to write that returnsTrue
if the data you have received so far is all of output that you expect to get.It is the call to
communicate()
that is killing your subprocess. According to the subprocess documentation thecommunicate()
method will:What you want to do is interact directly with the
POpen
object'sstdin
andstdout
properties directly to communicate with the subprocess. However, the documentation advises against this saying:So you either need to implement your own workarounds for potential deadlocks, or hope that someone has written an asynchronous subprocess module for you.
Edit: Here's a quick'n'dirty example of how the asynchronous subprocess module could be used:
When I run this, it prints:
I think you're looking for
you could create a list of Popens and then call communicate on each element in another loop. something like this
this way it won't have to wait until after all the Popens have started