How to Spawn a process with P_NOWAIT and pass it some data ?

Nick Craig-Wood nick at craig-wood.com
Thu May 21 15:29:55 EDT 2009


Barak, Ron <Ron.Barak at lsi.com> wrote:
>  This is my first try at IPC in Python, and I would like to ask your help wi=
>  th the following problem:
> 
>  I would like to spawn a process with P_NOWAIT, and pass some data to the ch=
>  ild process.
> 
>  I created two scripts to try IPC (in a blocking way):
> 
>  $ cat subprocess_sender.py
>  #!/usr/bin/env python
> 
>  import subprocess
> 
>  proc = subprocess.Popen(["python", "-u", "subprocess_receiver.py"],
>  stdin=subprocess.PIPE, shell=True)

You don't need shell=True here I wouldn't have thought.  It is a bad
idea in general.

>  proc.communicate(input="this is sent from subprocess_sender.py")[0]
>  proc.stdin.close()
>  and
> 
>  $ cat subprocess_receiver.py
>  #!/usr/bin/env python
> 
>  import sys
> 
>  print sys.stdin.readline()
> 
>  These scripts intercommunicate nicely:
> 
>  $ python -u  subprocess_sender.py
>  this is sent from subprocess_sender.py
[snip]
>  Can anyone suggest what is the correct way to implement P_NOWAIT and still
>  be able to communicate with the child process ?

You've written it already!  subprocess doesn't wait for a processes
until you call the communicate or wait methods.

If you want to communicate with the subprocess but not block waiting
for all of its output then use the file handle proc.stdout, eg

------------------------------------------------------------
import subprocess
proc = subprocess.Popen(["python", "-u", "subprocess_receiver.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=0)
proc.stdin.write("10\n")
proc.stdin.write("this is sent from subprocess_sender.py\n")
proc.stdin.close()
while True:
    line = proc.stdout.readline()
    if not line:
        break
    print "Received %r" % line
proc.wait()
------------------------------------------------------------
# subprocess_receiver.py

import sys
import time

times = int(sys.stdin.readline())
line = sys.stdin.readline().rstrip()

for x in range(times):
    print "%d: %s" % (x, line)
    time.sleep(1)
------------------------------------------------------------
$ python subprocess_test3.py
Received '0: this is sent from subprocess_sender.py\n'
Received '1: this is sent from subprocess_sender.py\n'
Received '2: this is sent from subprocess_sender.py\n'
Received '3: this is sent from subprocess_sender.py\n'
Received '4: this is sent from subprocess_sender.py\n'
Received '5: this is sent from subprocess_sender.py\n'
Received '6: this is sent from subprocess_sender.py\n'
Received '7: this is sent from subprocess_sender.py\n'
Received '8: this is sent from subprocess_sender.py\n'
Received '9: this is sent from subprocess_sender.py\n'
Received '10: this is sent from subprocess_sender.py\n'
(printed with a 1 second pause between each line)
------------------------------------------------------------

If you want to interact with a subprocess (eg send, receive, send,
receive) then use the pexpect module - buffering in subprocess will
cause you nothing but pain otherwise!

>  (Or, is there a way to create a subprocess.Popen object from what I assume =
>  is the process handle integer ?)

Errr, not as far as I know.

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list