[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

draining pipes simultaneously

Dmitry Teslenko

3/5/2008 9:34:00 AM

Hello!
Here's my implementation of a function that executes some command and
drains stdout/stderr invoking other functions for every line of
command output:

def __execute2_drain_pipe(queue, pipe):
for line in pipe:
queue.put(line)
return

def execute2(command, out_filter = None, err_filter = None):
p = subprocess.Popen(command , shell=True, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, env = os.environ)

qo = Queue.Queue()
qe = Queue.Queue()

to = threading.Thread(target = __execute2_drain_pipe, args = (qo, p.stdout))
to.start()
time.sleep(0)
te = threading.Thread(target = __execute2_drain_pipe, args = (qe, p.stderr))
te.start()

while to.isAlive() or te.isAlive():
try:
line = qo.get()
if out_filter:
out_filter(line)
qo.task_done()
except Queue.Empty:
pass

try:
line = qe.get()
if err_filter:
err_filter(line)
qe.task_done()
except Queue.Empty:
pass

to.join()
te.join()
return p.wait()

Problem is my implementation is buggy and function hungs when there's
empty stdout/stderr. Can I have your feedback?
9 Answers

Francesco Bochicchio

3/5/2008 10:34:00 AM

0

On 5 Mar, 10:33, "Dmitry Teslenko" <dtesle...@gmail.com> wrote:
> Hello!
> Here's my implementation of a function that executes some command and
> drains stdout/stderr invoking other functions for every line of
> command output:
>
> def __execute2_drain_pipe(queue, pipe):
>         for line in pipe:
>                 queue.put(line)
>         return
>
> def execute2(command, out_filter = None, err_filter = None):
>         p = subprocess.Popen(command , shell=True, stdin = subprocess.PIPE, >                 stdout = subprocess.PIPE, stderr = subprocess.PIPE, >                 env = os.environ)
>
>         qo = Queue.Queue()
>         qe = Queue.Queue()
>
>         to = threading.Thread(target = __execute2_drain_pipe, >                 args = (qo, p.stdout))
>         to.start()
>         time.sleep(0)
>         te = threading.Thread(target = __execute2_drain_pipe, >                 args = (qe, p.stderr))
>         te.start()
>
>         while to.isAlive() or te.isAlive():
>                 try:
>                         line = qo.get()
>                         if out_filter:
>                                 out_filter(line)
>                         qo.task_done()
>                 except Queue.Empty:
>                         pass
>
>                 try:
>                         line = qe.get()
>                         if err_filter:
>                                 err_filter(line)
>                         qe.task_done()
>                 except Queue.Empty:
>                         pass
>
>         to.join()
>         te.join()
>         return p.wait()
>
> Problem is my implementation is buggy and function hungs when there's
> empty stdout/stderr. Can I have your feedback?

The Queue.get method by default is blocking. The documentation is not
100% clear about that (maybe it should report
the full python definition of the function parameters, which makes
self-evident the default value) but if you do
help(Queue.Queue) in a python shell you will see it.

Hence, try using a timeout or a non-blocking get (but in case of a non
blocking get you should add a delay in the
loop, or you will poll the queues at naximum speed and maybe prevent
the other threads from accessing them).

Ciao
-----
FB

Dmitry Teslenko

3/5/2008 12:04:00 PM

0

On Wed, Mar 5, 2008 at 1:34 PM, <bockman@virgilio.it> wrote:
> The Queue.get method by default is blocking. The documentation is not
> 100% clear about that (maybe it should report
> the full python definition of the function parameters, which makes
> self-evident the default value) but if you do
> help(Queue.Queue) in a python shell you will see it.

> Hence, try using a timeout or a non-blocking get (but in case of a non
> blocking get you should add a delay in the
> loop, or you will poll the queues at naximum speed and maybe prevent
> the other threads from accessing them).

Thanks for advice! Finally I came up to following loop:

while to.isAlive() or te.isAlive():
try:
while True:
line = qo.get(False)
if out_filter:
out_filter(line)
except Queue.Empty:
pass

try:
while True:
line = qe.get(False)
if err_filter:
err_filter(line)
except Queue.Empty:
pass

Inserting delay in the beginning of the loop causes feeling of command
taking long to start and delay at the end of the loop may cause of
data loss when both thread became inactive during delay.

Francesco Bochicchio

3/5/2008 12:40:00 PM

0


>
> Inserting delay in the beginning of the loop causes feeling of command
> taking long to start and delay at the end of the loop may cause of
> data loss when both thread became inactive during delay.

time.sleep() pauses ony the thread that executes it, not the
others. And queue objects can hold large amount of data (if you have
the RAM),
so unless your subprocess is outputting data very fast, you should not
have data loss.
Anyway, if it works for you ... :-)

Ciao
-----
FB

Dmitry Teslenko

3/5/2008 2:56:00 PM

0

On Wed, Mar 5, 2008 at 3:39 PM, <bockman@virgilio.it> wrote:
> time.sleep() pauses ony the thread that executes it, not the
> others. And queue objects can hold large amount of data (if you have
> the RAM),
> so unless your subprocess is outputting data very fast, you should not
> have data loss.
> Anyway, if it works for you ... :-)

After some testing I'll agree :) Without time.sleep() in main thread
python eats up all aviable processor time

greatwichjohn@hotmail.com

2/17/2011 8:27:00 PM

0

On Feb 17, 4:27 pm, "seymour.shabow" <seymour.sha...@gmail.com> wrote:
> Ron Lyons wrote:
> > On Feb 17, 3:16 pm, darimont <darimo...@aol.com> wrote:
> >> My son that lives in Beaumont Texas called me yesterday morning and
> >> said he heard a commercial on the radio about the new Rolling Stone
> >> pin on his way to work. First time I every heard of them on a radio
> >> commercial.
>
> > This can't be true.  Everybody on RGP says that Stern is horrible at
> > Marketing.  Therefore, your son must be lying, or RGP is full of it.
>
> > :)
>
> > Ron
>
> Or, he heard a commercial for the Texas Pinball Festival, where 3
> rolling stones machines will be....

I purchased a new Rolling Stones & Iron Man for tournament play at
Texas Pinball Festival.

darimont

2/17/2011 8:28:00 PM

0

On Feb 17, 2:18 pm, Ron Lyons <rlyo...@carolina.rr.com> wrote:
> On Feb 17, 3:16 pm, darimont <darimo...@aol.com> wrote:
>
> > My son that lives in Beaumont Texas called me yesterday morning and
> > said he heard a commercial on the radio about the new Rolling Stone
> > pin on his way to work. First time I every heard of them on a radio
> > commercial.
>
> This can't be true.  Everybody on RGP says that Stern is horrible at
> Marketing.  Therefore, your son must be lying, or RGP is full of it.
>
> :)
>
> Ron

Why the hell would he lye about it.

Deadly

2/17/2011 8:30:00 PM

0

Not only did you miss the sarcasm but you also missed the smiley
face.

-=Chris=-

On Feb 17, 12:27 pm, darimont <darimo...@aol.com> wrote:
> On Feb 17, 2:18 pm, Ron Lyons <rlyo...@carolina.rr.com> wrote:
>
> > On Feb 17, 3:16 pm, darimont <darimo...@aol.com> wrote:
>
> > > My son that lives in Beaumont Texas called me yesterday morning and
> > > said he heard a commercial on the radio about the new Rolling Stone
> > > pin on his way to work. First time I every heard of them on a radio
> > > commercial.
>
> > This can't be true.  Everybody on RGP says that Stern is horrible at
> > Marketing.  Therefore, your son must be lying, or RGP is full of it.
>
> > :)
>
> > Ron
>
> Why the hell would he lye about it.

darimont

2/17/2011 8:39:00 PM

0

On Feb 17, 2:27 pm, darimont <darimo...@aol.com> wrote:
> On Feb 17, 2:18 pm, Ron Lyons <rlyo...@carolina.rr.com> wrote:
>
> > On Feb 17, 3:16 pm, darimont <darimo...@aol.com> wrote:
>
> > > My son that lives in Beaumont Texas called me yesterday morning and
> > > said he heard a commercial on the radio about the new Rolling Stone
> > > pin on his way to work. First time I every heard of them on a radio
> > > commercial.
>
> > This can't be true.  Everybody on RGP says that Stern is horrible at
> > Marketing.  Therefore, your son must be lying, or RGP is full of it.
>
> > :)
>
> > Ron
>
> Why the hell would he lye about it.

I just talked to him and he said it was on the Bob and Tom morning
show and they were talking about pinball and mentioned the new rolling
stones. I think Bob and Tom are broadcast all over the states.

darimont

2/17/2011 8:43:00 PM

0

On Feb 17, 2:29 pm, CEllison <clell...@gmail.com> wrote:
> Not only did you miss the sarcasm but you also missed the smiley
> face.
>
> -=Chris=-
>
> On Feb 17, 12:27 pm, darimont <darimo...@aol.com> wrote:
>
> > On Feb 17, 2:18 pm, Ron Lyons <rlyo...@carolina.rr.com> wrote:
>
> > > On Feb 17, 3:16 pm, darimont <darimo...@aol.com> wrote:
>
> > > > My son that lives in Beaumont Texas called me yesterday morning and
> > > > said he heard a commercial on the radio about the new Rolling Stone
> > > > pin on his way to work. First time I every heard of them on a radio
> > > > commercial.
>
> > > This can't be true.  Everybody on RGP says that Stern is horrible at
> > > Marketing.  Therefore, your son must be lying, or RGP is full of it.
>
> > > :)
>
> > > Ron
>
> > Why the hell would he lye about it.
>
>

Sorry, yes I did. Not very attentive today.