Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Need feedback on subprocess-using function

Reply
Thread Tools

Need feedback on subprocess-using function

 
 
gb345
Guest
Posts: n/a
 
      10-03-2009



I'm relatively new to Python, and I'm trying to get the hang of
using Python's subprocess module. As an exercise, I wrote the Tac
class below, which can prints output to a file "in reverse order",
by piping it through the Unix tac utility. (The idea is to delegate
the problem of managing the memory for an arbitrarily large task
to tac.)

class Tac(object):
def __init__(self, path):
out = open(path, 'w')
self.pipe = subprocess.Popen(['tac'], stdout=out,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
def prn(self, string):
try:
self.pipe.stdin.write('%s\n' % string)
except:
self.close()
raise

def close(self):
p = self.pipe
p.stdin.close()
err = p.stderr.read()
if err:
raise OSError(err)

This works OK, as far as I can tell, but I'm not sure that I've
dotted all the i's and crossed all the t's... E.g., I had to add
the line "p.stdin.close()" to the close method when I when I ran
into sporadic deadlock at the p.stderr.read() statement. Are there
other similar problems lurking in this code? Also, there's no
robust mechanism for invoking this close method in case of an
exception (unless the exception happens during the execution of
prn).

Any comments and suggestions would be greatly appreciated.

G
 
Reply With Quote
 
 
 
 
Nobody
Guest
Posts: n/a
 
      10-05-2009
On Sat, 03 Oct 2009 13:21:00 +0000, gb345 wrote:

> I'm relatively new to Python, and I'm trying to get the hang of
> using Python's subprocess module. As an exercise, I wrote the Tac
> class below, which can prints output to a file "in reverse order",
> by piping it through the Unix tac utility. (The idea is to delegate
> the problem of managing the memory for an arbitrarily large task
> to tac.)


> self.pipe = subprocess.Popen(['tac'], stdout=out,
> stdin=subprocess.PIPE,
> stderr=subprocess.PIPE)


> This works OK, as far as I can tell, but I'm not sure that I've
> dotted all the i's and crossed all the t's... E.g., I had to add
> the line "p.stdin.close()" to the close method when I when I ran
> into sporadic deadlock at the p.stderr.read() statement. Are there
> other similar problems lurking in this code?


Yep. If the process writes more than a buffer-full of data to stderr, it
will deadlock. tac will block trying to write to stderr, and won't be
reading its stdin, so your program will block trying to write to tac.

This is why the POSIX popen() call only lets you attach a pipe to stdin or
stdout but not both.

If you want a "double-ended" slave process, you need to use polling or
non-blocking I/O or asynchronous I/O or multiple threads. I'm not aware of
any single solution which works on all platforms.

The easiest way around this problem is to redirect stderr to a temporary
file and read in the file's contents in the close() method.

 
Reply With Quote
 
 
 
 
ryles
Guest
Posts: n/a
 
      10-05-2009
On Oct 4, 9:46*pm, Nobody <nob...@nowhere.com> wrote:
> On Sat, 03 Oct 2009 13:21:00 +0000, gb345 wrote:
> > I'm relatively new to Python, and I'm trying to get the hang of
> > using Python's subprocess module. *As an exercise, I wrote the Tac
> > class below, which can prints output to a file "in reverse order",
> > by piping it through the Unix tac utility. *(The idea is to delegate
> > the problem of managing the memory for an arbitrarily large task
> > to tac.)
> > * * * * self.pipe = subprocess.Popen(['tac'], stdout=out,
> > * * * * * * * * * * * * * * * * * * *stdin=subprocess.PIPE,
> > * * * * * * * * * * * * * * * * * * *stderr=subprocess.PIPE)
> > This works OK, as far as I can tell, but I'm not sure that I've
> > dotted all the i's and crossed all the t's... *E.g., I had to add
> > the line "p.stdin.close()" to the close method when I when I ran
> > into sporadic deadlock at the p.stderr.read() statement. *Are there
> > other similar problems lurking in this code?

>
> Yep. If the process writes more than a buffer-full of data to stderr, it
> will deadlock. tac will block trying to write to stderr, and won't be
> reading its stdin, so your program will block trying to write to tac.
>
> This is why the POSIX popen() call only lets you attach a pipe to stdin or
> stdout but not both.
>
> If you want a "double-ended" slave process, you need to use polling or
> non-blocking I/O or asynchronous I/O or multiple threads. I'm not aware of
> any single solution which works on all platforms.
>
> The easiest way around this problem is to redirect stderr to a temporary
> file and read in the file's contents in the close() method.


There is also Popen.communicate():

http://docs.python.org/library/subpr...en.communicate
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      10-07-2009
On Mon, 05 Oct 2009 02:29:38 -0700, ryles wrote:

>> If you want a "double-ended" slave process, you need to use polling or
>> non-blocking I/O or asynchronous I/O or multiple threads. I'm not aware of
>> any single solution which works on all platforms.
>>
>> The easiest way around this problem is to redirect stderr to a temporary
>> file and read in the file's contents in the close() method.

>
> There is also Popen.communicate():


That doesn't help if you want to write data incrementally.

You could always lift the code from Popen._communicate(), which uses
threads for Windows and select() for POSIX.

 
Reply With Quote
 
gb345
Guest
Posts: n/a
 
      10-10-2009
In <> Nobody <> writes:

>You could always lift the code from Popen._communicate(), which uses
>threads for Windows and select() for POSIX.


Thanks. A lot of useful advice in your replies.

G.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
feedback on function introspection in argparse Yuv Python 5 11-14-2009 03:44 PM
Feedback from feedback on MCP questions Matt Adamson Microsoft Certification 0 04-27-2009 11:13 AM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Feedback on this template function JohanS C++ 1 08-25-2004 02:05 AM
Need 70-229 feedback Vlodron MCSE 0 10-19-2003 04:09 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57