zsh-users
 help / color / mirror / code / Atom feed
* wait for the next process to finish
@ 2011-12-12 15:46 Anthony R Fletcher
  2011-12-12 16:37 ` TJ Luoma
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Anthony R Fletcher @ 2011-12-12 15:46 UTC (permalink / raw)
  To: zsh-users

I just realised that the 'wait' command will either wait for specified
jobs or all jobs and nothing in between. The manual says "If job is not
given then all currently active child processes are waited for.".

So 
	sleep 30 &
	sleep 10 &
	sleep 30 &
	sleep 30 &
	wait
waits for all the sleeps to finish.

How can I wait for just the next job to finish?

			Anthony.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 15:46 wait for the next process to finish Anthony R Fletcher
@ 2011-12-12 16:37 ` TJ Luoma
  2011-12-12 19:41 ` Wayne Davison
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 19+ messages in thread
From: TJ Luoma @ 2011-12-12 16:37 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 714 bytes --]

On Mon, Dec 12, 2011 at 10:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:

> I just realised that the 'wait' command will either wait for specified
> jobs or all jobs and nothing in between. The manual says "If job is not
> given then all currently active child processes are waited for.".
>
> So
>        sleep 30 &
>        sleep 10 &
>        sleep 30 &
>        sleep 30 &
>        wait
> waits for all the sleeps to finish.
>
> How can I wait for just the next job to finish?
>

Just don't run it in the background.

or do it like this:

(job1 ; job2)

or, if you want to make sure that job2 only runs if job1 succeeds:

(job1 && job2)

TjL

ps - my apologies if I am misunderstanding the question




>

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 15:46 wait for the next process to finish Anthony R Fletcher
  2011-12-12 16:37 ` TJ Luoma
@ 2011-12-12 19:41 ` Wayne Davison
  2011-12-13  7:15   ` Martin Richter
  2011-12-13 16:07   ` Rory Mulvaney
  2011-12-13 10:01 ` Peter Stephenson
  2011-12-13 17:45 ` Stephane Chazelas
  3 siblings, 2 replies; 19+ messages in thread
From: Wayne Davison @ 2011-12-12 19:41 UTC (permalink / raw)
  To: zsh-users

[-- Attachment #1: Type: text/plain, Size: 765 bytes --]

On Mon, Dec 12, 2011 at 7:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:

> How can I wait for just the next job to finish?
>

One thing that may help you is TRAPCHLD.  Sadly, the signal handler doesn't
tell you what pid it is reacting to, nor the exit code.

TRAPCHLD() {
    echo here
    oldpids=($pids)
    pids=( )
    for p in $oldpids; do
        if kill -0 $p 2>/dev/null; then
            pids+=$p
        else
            #wait $p # Sadly, this doesn't work
            echo $p exited
        fi
    done
}
pids=( )
sleep 10 &
pids+=$!
sleep 20 &
pids+=$!
(sleep 15; false) &
pids+=$!
echo $pids
wait
echo done

It might be nice to set an environment parameter with the pid and status
info right before the dotrap(SIGCHLD) call in jobs.c.

..wayne..

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 19:41 ` Wayne Davison
@ 2011-12-13  7:15   ` Martin Richter
  2011-12-13 16:07   ` Rory Mulvaney
  1 sibling, 0 replies; 19+ messages in thread
From: Martin Richter @ 2011-12-13  7:15 UTC (permalink / raw)
  To: zsh-users

On Monday December 12 2011, Wayne Davison wrote:
> On Mon, Dec 12, 2011 at 7:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:
> 
> > How can I wait for just the next job to finish?

This is probably not exactly what you want and it isn't pretty either. But you could use `make' for this and use the -j flag for telling it to process stuff in parallel:


#---------------------------

make -j 4 -f =( cat <<EOF
default: task1 task2 task3 task4 task_finally

task1:
        @echo task1
        sleep 2
        @echo task1 finished

task2:
        @echo task2
        sleep 7
        @echo task2 finished

task3:
        @echo task3
        sleep 4
        @echo task3 finished

task4:
        @echo task4
        sleep 10
        @echo task4 finished

task_finally:
        @echo finally
EOF)

#---------------------------

However it is not really customizable and I think it is not really meant to be used that way. If this solution does not already make you shudder, you might also be able to construct something likewise using xargs and the --max-procs switch.

Martin


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 15:46 wait for the next process to finish Anthony R Fletcher
  2011-12-12 16:37 ` TJ Luoma
  2011-12-12 19:41 ` Wayne Davison
@ 2011-12-13 10:01 ` Peter Stephenson
  2011-12-13 17:10   ` Bart Schaefer
  2011-12-13 17:45 ` Stephane Chazelas
  3 siblings, 1 reply; 19+ messages in thread
From: Peter Stephenson @ 2011-12-13 10:01 UTC (permalink / raw)
  To: zsh-users

On Mon, 12 Dec 2011 10:46:01 -0500
Anthony R Fletcher <arif@mail.nih.gov> wrote:
> I just realised that the 'wait' command will either wait for specified
> jobs or all jobs and nothing in between. The manual says "If job is not
> given then all currently active child processes are waited for.".
> 
> So 
> 	sleep 30 &
> 	sleep 10 &
> 	sleep 30 &
> 	sleep 30 &
> 	wait
> waits for all the sleeps to finish.
> 
> How can I wait for just the next job to finish?

Certainly the shell internals don't help you here.  There's code to look
at a specific job, decide if it's still going, and exit when it isn't,
which is behind the wait builtin with an argument.  There's nothing to
loop over all jobs, decide what's still going, wait for something to
happen, then work out what it was and hence if it can stop waiting.

The reason waiting for all jobs works is simply that it waits for jobs
in order; if an earlier job exits first it gets handled by the signal
handler, but the shell foreground doesn't notice until the job it's
actually waiting for exits, then it carries on down the list and picks
up anything that's already exited.

-- 
Peter Stephenson <pws@csr.com>            Software Engineer
Tel: +44 (0)1223 692070                   Cambridge Silicon Radio Limited
Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom
More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 19:41 ` Wayne Davison
  2011-12-13  7:15   ` Martin Richter
@ 2011-12-13 16:07   ` Rory Mulvaney
  2011-12-13 16:45     ` Jérémie Roquet
                       ` (2 more replies)
  1 sibling, 3 replies; 19+ messages in thread
From: Rory Mulvaney @ 2011-12-13 16:07 UTC (permalink / raw)
  To: zsh-users; +Cc: Wayne Davison, Anthony R Fletcher

On Mon, 12 Dec 2011, Wayne Davison wrote:

> On Mon, Dec 12, 2011 at 7:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:
> 
> > How can I wait for just the next job to finish?
> >
> 
> One thing that may help you is TRAPCHLD.  Sadly, the signal handler doesn't
> tell you what pid it is reacting to, nor the exit code.
> 
> TRAPCHLD() {
>     echo here
>     oldpids=($pids)
>     pids=( )
>     for p in $oldpids; do
>         if kill -0 $p 2>/dev/null; then
>             pids+=$p
>         else
>             #wait $p # Sadly, this doesn't work
>             echo $p exited
>         fi
>     done
> }
> pids=( )
> sleep 10 &
> pids+=$!
> sleep 20 &
> pids+=$!
> (sleep 15; false) &
> pids+=$!
> echo $pids
> wait
> echo done
> 
> It might be nice to set an environment parameter with the pid and status
> info right before the dotrap(SIGCHLD) call in jobs.c.
> 
> ..wayne..
> 

To clarify (I think this is fairly simple), you can supply the process id 
as a parameter to 'wait', and though the $! method seems rather clumsy to 
retrieve the pid (since you have to retrieve it somehow in the next 
command after spawning the background process), it seems to work mostly in 
general.

So you could do:

sleep 20000 &
sleep 20 &
pid=$!
wait $pid

That will just wait for the sleep 20 process to complete while the sleep 
20000 process still runs in the background.

For further reference, I see that $! is documented in sec. 15.5 
(Parameters set by the shell) in the zsh texinfo manual.

-Rory


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:07   ` Rory Mulvaney
@ 2011-12-13 16:45     ` Jérémie Roquet
  2011-12-13 16:59       ` Anthony R Fletcher
  2011-12-13 16:49     ` Christoph (Stucki) von Stuckrad
  2011-12-13 17:04     ` Rory Mulvaney
  2 siblings, 1 reply; 19+ messages in thread
From: Jérémie Roquet @ 2011-12-13 16:45 UTC (permalink / raw)
  To: Rory Mulvaney; +Cc: zsh-users, Wayne Davison, Anthony R Fletcher

Hi,

2011/12/13 Rory Mulvaney <rorymulv@gmail.com>:
> To clarify (I think this is fairly simple), you can supply the process id
> as a parameter to 'wait', and though the $! method seems rather clumsy to
> retrieve the pid (since you have to retrieve it somehow in the next
> command after spawning the background process), it seems to work mostly in
> general.
>
> So you could do:
>
> sleep 20000 &
> sleep 20 &
> pid=$!
> wait $pid
>
> That will just wait for the sleep 20 process to complete while the sleep
> 20000 process still runs in the background.

Actually, it'll always wait for the last spawned job, not for the
first job to finish.

If you spawn them in the reverse order, ie:

sleep 20 &
sleep 20000 &
pid=$!
wait $pid

This will wait for the sleep 20000 process, even if the sleep 20 has
finished for long.

Best regards,

-- 
Jérémie


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:07   ` Rory Mulvaney
  2011-12-13 16:45     ` Jérémie Roquet
@ 2011-12-13 16:49     ` Christoph (Stucki) von Stuckrad
  2011-12-13 17:31       ` Bart Schaefer
  2011-12-13 17:04     ` Rory Mulvaney
  2 siblings, 1 reply; 19+ messages in thread
From: Christoph (Stucki) von Stuckrad @ 2011-12-13 16:49 UTC (permalink / raw)
  To: zsh-users

On Tue, 13 Dec 2011, Rory Mulvaney wrote:

> > On Mon, Dec 12, 2011 at 7:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:
> > 
> > > How can I wait for just the next job to finish?
> > >
> > 
> > One thing that may help you is TRAPCHLD.  Sadly, the signal handler doesn't
> > tell you what pid it is reacting to, nor the exit code.
> > 
> > TRAPCHLD() {
...
> > }
...
> > It might be nice to set an environment parameter with the pid and status
> > info right before the dotrap(SIGCHLD) call in jobs.c.
...

This sounds very promising, because you then could 'parallelize'
a loop by feeding it new processes when 'one of the runnig' dies.

I hope for something in the line of:

TRAPCHILD() { ... ... ... }
pids=( )
for i in some paramters given
do
        if [[ $#pids >= $MAXPARALLEL ]]
        then sleep 1 # and TRAPCHILD will remove 'done's
        else
                call $i &
                pids+=$!
        fi
done

SO one might be able to keep a bunch of CPUS working
for 'one given loop' without needing to know which
case is done first? (And only if the parallelities
do not break something like tempfiles, stderr, etc ...)

Stucki


-- 
Christoph von Stuckrad      * * |nickname |Mail <stucki@mi.fu-berlin.de> \
Freie Universitaet Berlin   |/_*|'stucki' |Tel(Mo.,Mi.):+49 30 838-75 459|
Mathematik & Informatik EDV |\ *|if online|  (Di,Do,Fr):+49 30 77 39 6600|
Takustr. 9 / 14195 Berlin   * * |on IRCnet|Fax(home):   +49 30 77 39 6601/


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:45     ` Jérémie Roquet
@ 2011-12-13 16:59       ` Anthony R Fletcher
  2011-12-13 18:08         ` Daniel Shahaf
  0 siblings, 1 reply; 19+ messages in thread
From: Anthony R Fletcher @ 2011-12-13 16:59 UTC (permalink / raw)
  To: zsh-users

> 2011/12/13 Rory Mulvaney <rorymulv@gmail.com>:
> > To clarify (I think this is fairly simple), you can supply the process id
> > as a parameter to 'wait', and though the $! method seems rather clumsy to
> > retrieve the pid (since you have to retrieve it somehow in the next
> > command after spawning the background process), it seems to work mostly in
> > general.
> >
> > So you could do:
> >
> > sleep 20000 &
> > sleep 20 &
> > pid=$!
> > wait $pid
> >
> > That will just wait for the sleep 20 process to complete while the sleep
> > 20000 process still runs in the background.
> 
> Actually, it'll always wait for the last spawned job, not for the
> first job to finish.
> 
> If you spawn them in the reverse order, ie:
> 
> sleep 20 &
> sleep 20000 &
> pid=$!
> wait $pid
> 
> This will wait for the sleep 20000 process, even if the sleep 20 has
> finished for long.

Yes, the need to to wait for any of the processes to end so I can start
another. Basically a poor man's batch system.

			Anthony.

-- 
Anthony R Fletcher        
  Room 2033, Building 12A,        http://dcb.cit.nih.gov/~arif
  National Institutes of Health,  arif@mail.nih.gov
  12A South Drive, Bethesda,      Phone: (+1) 301 402 1741.
  MD 20892-5624, USA.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:07   ` Rory Mulvaney
  2011-12-13 16:45     ` Jérémie Roquet
  2011-12-13 16:49     ` Christoph (Stucki) von Stuckrad
@ 2011-12-13 17:04     ` Rory Mulvaney
  2011-12-13 17:32       ` Anthony R Fletcher
  2 siblings, 1 reply; 19+ messages in thread
From: Rory Mulvaney @ 2011-12-13 17:04 UTC (permalink / raw)
  To: Rory Mulvaney; +Cc: zsh-users, Wayne Davison, Anthony R Fletcher

On Tue, 13 Dec 2011, Rory Mulvaney wrote:

> On Mon, 12 Dec 2011, Wayne Davison wrote:
> 
> > On Mon, Dec 12, 2011 at 7:46 AM, Anthony R Fletcher <arif@mail.nih.gov>wrote:
> > 
> > > How can I wait for just the next job to finish?
> > >
> > 
> > One thing that may help you is TRAPCHLD.  Sadly, the signal handler doesn't
> > tell you what pid it is reacting to, nor the exit code.
> > 
> > TRAPCHLD() {
> >     echo here
> >     oldpids=($pids)
> >     pids=( )
> >     for p in $oldpids; do
> >         if kill -0 $p 2>/dev/null; then
> >             pids+=$p
> >         else
> >             #wait $p # Sadly, this doesn't work
> >             echo $p exited
> >         fi
> >     done
> > }
> > pids=( )
> > sleep 10 &
> > pids+=$!
> > sleep 20 &
> > pids+=$!
> > (sleep 15; false) &
> > pids+=$!
> > echo $pids
> > wait
> > echo done
> > 
> > It might be nice to set an environment parameter with the pid and status
> > info right before the dotrap(SIGCHLD) call in jobs.c.
> > 
> > ..wayne..
> > 
> 
> To clarify (I think this is fairly simple), you can supply the process id 
> as a parameter to 'wait', and though the $! method seems rather clumsy to 
> retrieve the pid (since you have to retrieve it somehow in the next 
> command after spawning the background process), it seems to work mostly in 
> general.
> 
> So you could do:
> 
> sleep 20000 &
> sleep 20 &
> pid=$!
> wait $pid
> 
> That will just wait for the sleep 20 process to complete while the sleep 
> 20000 process still runs in the background.
> 
> For further reference, I see that $! is documented in sec. 15.5 
> (Parameters set by the shell) in the zsh texinfo manual.
> 

Sorry, now I realized that you want to want to wait for whichever 
background process finishes first.  I know that select (zsh/zselect) is 
used for this type of thing, which blocks until some file descriptor is 
ready for reading or writing.  It would possible but sort of complicated 
to hack that functionality into the case of waiting for pids.  I can 
imagine using coproc to get a file descriptor for each of the background 
processes.

Something like this (requiring a zsh version with anonymous functions):

pids=( )
R=( $RANDOM $RANDOM )
echo $R
coproc () { sleep $(( $R[1]/32767.0*20 )) ; echo $$ }
pids+=$!
# copy the coproc fd
exec 3<&p
coproc () { sleep $(( $R[2]/32767.0*20 )) ; echo $$ }
pids+=$!  
exec 4<&p
zmodload zsh/zselect
zselect -r 3 4
echo $reply

Then one could parse $reply.

I don't know, maybe there's a much easier way to create file descriptors 
for those processes?

-Rory


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 10:01 ` Peter Stephenson
@ 2011-12-13 17:10   ` Bart Schaefer
  2011-12-13 20:42     ` Rory Mulvaney
  0 siblings, 1 reply; 19+ messages in thread
From: Bart Schaefer @ 2011-12-13 17:10 UTC (permalink / raw)
  To: zsh-users

On Dec 13, 10:01am, Peter Stephenson wrote:
} Subject: Re: wait for the next process to finish
}
} On Mon, 12 Dec 2011 10:46:01 -0500
} Anthony R Fletcher <arif@mail.nih.gov> wrote:
} > I just realised that the 'wait' command will either wait for specified
} > jobs or all jobs and nothing in between. The manual says "If job is not
} > given then all currently active child processes are waited for.".
} > 
} > So 
} > 	sleep 30 &
} > 	sleep 10 &
} > 	sleep 30 &
} > 	sleep 30 &
} > 	wait
} > waits for all the sleeps to finish.
} > 
} > How can I wait for just the next job to finish?
} 
} Certainly the shell internals don't help you here.  There's code to look
} at a specific job, decide if it's still going, and exit when it isn't,
} which is behind the wait builtin with an argument.  There's nothing to
} loop over all jobs, decide what's still going, wait for something to
} happen, then work out what it was and hence if it can stop waiting.

What's "just the next job" mean here?

Wait until any one of the four jobs finishes, or wait until a specific
job (e.g., the first one started, and then the second one, and then
the third, etc.) finishes?

I think there have been some answers on this thread that assume one
meaning and some the other, and therefore are contradictory.  If it's
the first meaning (any job) then Wayne's TRAPCHLD suggestion is the
most helpful, but it's true the trap doesn't get useful information
about which child set it off, and on top of that the handler is not
called until the child is already removed from the job table, so even
if you could figure out which one it was you can't "wait" to get its
exit status (I don't think).

In the realm of ugly hacks, you could run each child as a coprocess
that ends with "print $?".  Stash away the coprocess file descriptor
each time you start one, and then when they're all running, start a
loop polling that list of descriptors with "read -t" until you find
one from which you can read.  What you read will be the exit status.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:49     ` Christoph (Stucki) von Stuckrad
@ 2011-12-13 17:31       ` Bart Schaefer
  0 siblings, 0 replies; 19+ messages in thread
From: Bart Schaefer @ 2011-12-13 17:31 UTC (permalink / raw)
  To: zsh-users

On Dec 13,  5:49pm, Christoph (Stucki) von Stuckrad wrote:
}
} This sounds very promising, because you then could 'parallelize'
} a loop by feeding it new processes when 'one of the runnig' dies.

That much you can do already.

    TRAPCHLD() {
       while (( ${#jobstates} < MAXPARALLEL ))
       do the background task &
       done
    }

(Of course you need some sort of other loop-ending condition, but you
get the idea.)

You don't really even need the trap for this, your original loop will
work fine as long as you examine ${(k)jobstates} as the list of PIDs
instead of trying to maintain your own array.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 17:04     ` Rory Mulvaney
@ 2011-12-13 17:32       ` Anthony R Fletcher
  2011-12-13 18:04         ` Jérémie Roquet
  0 siblings, 1 reply; 19+ messages in thread
From: Anthony R Fletcher @ 2011-12-13 17:32 UTC (permalink / raw)
  To: zsh-users


On 13 Dec 2011 at 11:04:44, Rory Mulvaney wrote:
> pids=( )
> R=( $RANDOM $RANDOM )
> echo $R
> coproc () { sleep $(( $R[1]/32767.0*20 )) ; echo $$ }
> pids+=$!
> # copy the coproc fd
> exec 3<&p
> coproc () { sleep $(( $R[2]/32767.0*20 )) ; echo $$ }
> pids+=$!  
> exec 4<&p
> zmodload zsh/zselect
> zselect -r 3 4
> echo $reply
> 
> Then one could parse $reply.
> 
> I don't know, maybe there's a much easier way to create file descriptors 
> for those processes?
> 
> -Rory

I was using this loop

  for f in *.txt
  do
	  what-ever-has-to-happen $f &
	  pwait 20
  done

where pwait is a function

  function pwait() {
          while [ $(jobs -rp | wc -l) -ge $1 ]
          do
		  # sleep 10
                  wait
          done
  }

(see http://superuser.com/questions/158165/parallel-shell-loops for one
example amongst many).

I was hoping that using "wait" would be better than using a "sleep 10".
But wait waits for them all and not just he last to finish. The nice
thing is that this is a small, easy loop and all the brains is in the
barrier function pwait. Sadly a sleep for 10 seconds is completely
arbitrary.

			Anthony.

-- 
Anthony R Fletcher        
  Room 2033, Building 12A,        http://dcb.cit.nih.gov/~arif
  National Institutes of Health,  arif@mail.nih.gov
  12A South Drive, Bethesda,      Phone: (+1) 301 402 1741.
  MD 20892-5624, USA.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-12 15:46 wait for the next process to finish Anthony R Fletcher
                   ` (2 preceding siblings ...)
  2011-12-13 10:01 ` Peter Stephenson
@ 2011-12-13 17:45 ` Stephane Chazelas
  3 siblings, 0 replies; 19+ messages in thread
From: Stephane Chazelas @ 2011-12-13 17:45 UTC (permalink / raw)
  To: zsh-users

2011-12-12 10:46:01 -0500, Anthony R Fletcher:
> I just realised that the 'wait' command will either wait for specified
> jobs or all jobs and nothing in between. The manual says "If job is not
> given then all currently active child processes are waited for.".
> 
> So 
> 	sleep 30 &
> 	sleep 10 &
> 	sleep 30 &
> 	sleep 30 &
> 	wait
> waits for all the sleeps to finish.
> 
> How can I wait for just the next job to finish?
[...]

What about:

{
(sleep 4; echo A) &
(sleep 1; echo B) &
(sleep 8; echo C) &
(sleep 2; echo D) &
(sleep 7; echo E) &
(sleep 3; echo F) &
} | while read task; do
  date +"%T: $task finished"
done

17:44:17: B finished
17:44:18: D finished
17:44:19: F finished
17:44:20: A finished
17:44:23: E finished
17:44:24: C finished

-- 
Stephane


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 17:32       ` Anthony R Fletcher
@ 2011-12-13 18:04         ` Jérémie Roquet
  2011-12-13 18:20           ` Stephane Chazelas
  0 siblings, 1 reply; 19+ messages in thread
From: Jérémie Roquet @ 2011-12-13 18:04 UTC (permalink / raw)
  To: zsh-users

2011/12/13 Anthony R Fletcher <arif@mail.nih.gov>:
> I was using this loop
>
>  for f in *.txt
>  do
>          what-ever-has-to-happen $f &
>          pwait 20
>  done
>
> where pwait is a function
>
>  function pwait() {
>          while [ $(jobs -rp | wc -l) -ge $1 ]
>          do
>                  # sleep 10
>                  wait
>          done
>  }
>
> (see http://superuser.com/questions/158165/parallel-shell-loops for one
> example amongst many).
>
> I was hoping that using "wait" would be better than using a "sleep 10".
> But wait waits for them all and not just he last to finish. The nice
> thing is that this is a small, easy loop and all the brains is in the
> barrier function pwait. Sadly a sleep for 10 seconds is completely
> arbitrary.

I'm wondering if you're not just looking for zargs :-)

autoload -U zargs
zargs -n 1 -P 20 *.txt -- what-ever-has-to-happen

Best regards,

-- 
Jérémie


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 16:59       ` Anthony R Fletcher
@ 2011-12-13 18:08         ` Daniel Shahaf
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Shahaf @ 2011-12-13 18:08 UTC (permalink / raw)
  To: zsh-users

Anthony R Fletcher wrote on Tue, Dec 13, 2011 at 11:59:29 -0500:
> > 2011/12/13 Rory Mulvaney <rorymulv@gmail.com>:
> > > To clarify (I think this is fairly simple), you can supply the process id
> > > as a parameter to 'wait', and though the $! method seems rather clumsy to
> > > retrieve the pid (since you have to retrieve it somehow in the next
> > > command after spawning the background process), it seems to work mostly in
> > > general.
> > >
> > > So you could do:
> > >
> > > sleep 20000 &
> > > sleep 20 &
> > > pid=$!
> > > wait $pid
> > >
> > > That will just wait for the sleep 20 process to complete while the sleep
> > > 20000 process still runs in the background.
> > 
> > Actually, it'll always wait for the last spawned job, not for the
> > first job to finish.
> > 
> > If you spawn them in the reverse order, ie:
> > 
> > sleep 20 &
> > sleep 20000 &
> > pid=$!
> > wait $pid
> > 
> > This will wait for the sleep 20000 process, even if the sleep 20 has
> > finished for long.
> 
> Yes, the need to to wait for any of the processes to end so I can start
> another. Basically a poor man's batch system.

'xargs -P' and 'make -j' were already suggested upthread; is the task
you're trying to parallelize not suitable for those approaches?


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 18:04         ` Jérémie Roquet
@ 2011-12-13 18:20           ` Stephane Chazelas
  2011-12-13 19:19             ` Anthony R Fletcher
  0 siblings, 1 reply; 19+ messages in thread
From: Stephane Chazelas @ 2011-12-13 18:20 UTC (permalink / raw)
  To: Jérémie Roquet; +Cc: zsh-users

2011-12-13 19:04:12 +0100, Jérémie Roquet:
[...]
> I'm wondering if you're not just looking for zargs :-)
[...]

Or GNU parallel or pexec.

-- 
Stephane


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 18:20           ` Stephane Chazelas
@ 2011-12-13 19:19             ` Anthony R Fletcher
  0 siblings, 0 replies; 19+ messages in thread
From: Anthony R Fletcher @ 2011-12-13 19:19 UTC (permalink / raw)
  To: Jérémie Roquet, zsh-users

On 13 Dec 2011 at 18:20:03, Stephane Chazelas wrote:
> 2011-12-13 19:04:12 +0100, Jérémie Roquet:
> [...]
> > I'm wondering if you're not just looking for zargs :-)
> [...]
> 
> Or GNU parallel or pexec.
> 

I considered GNU parallel but the loop seems do much easier for what I
wanted to do. pexec needs to be compiled - too hard for this job. The
loop idea was just too easy to use.

I didn't know about zargs but I'll play with it. Thanks.

		Anthony.


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: wait for the next process to finish
  2011-12-13 17:10   ` Bart Schaefer
@ 2011-12-13 20:42     ` Rory Mulvaney
  0 siblings, 0 replies; 19+ messages in thread
From: Rory Mulvaney @ 2011-12-13 20:42 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-users, rorymulv

On Tue, 13 Dec 2011, Bart Schaefer wrote:

> 
> In the realm of ugly hacks, you could run each child as a coprocess
> that ends with "print $?".  Stash away the coprocess file descriptor
> each time you start one, and then when they're all running, start a
> loop polling that list of descriptors with "read -t" until you find
> one from which you can read.  What you read will be the exit status.
> 

Yes, this is what I demonstrated in my second email, but the idea about 
using TRAPCHLD is probably easiest, since you could have your child 
processes print out any info about the process such as the return code, 
redirecting it to a single file descriptor owned by a designated 
information-relay coproc (which merely echo's its stdin to stdout), and 
then parse the output from the coproc in TRAPCHLD, which is apparently one 
of the available trap functions running whenever a signal arrives, since 
SIGCHLD is a signal from signal(7) (I didn't realize that before).

On Tue, 13 Dec 2011, Bart Schaefer wrote:

>
>     TRAPCHLD() {
>        while (( ${#jobstates} < MAXPARALLEL ))
>        do the background task &
>        done
>     }
>
> (Of course you need some sort of other loop-ending condition, but you
> get the idea.)
>
> You don't really even need the trap for this, your original loop will
> work fine as long as you examine ${(k)jobstates} as the list of PIDs
> instead of trying to maintain your own array.
>


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-12-13 20:45 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-12 15:46 wait for the next process to finish Anthony R Fletcher
2011-12-12 16:37 ` TJ Luoma
2011-12-12 19:41 ` Wayne Davison
2011-12-13  7:15   ` Martin Richter
2011-12-13 16:07   ` Rory Mulvaney
2011-12-13 16:45     ` Jérémie Roquet
2011-12-13 16:59       ` Anthony R Fletcher
2011-12-13 18:08         ` Daniel Shahaf
2011-12-13 16:49     ` Christoph (Stucki) von Stuckrad
2011-12-13 17:31       ` Bart Schaefer
2011-12-13 17:04     ` Rory Mulvaney
2011-12-13 17:32       ` Anthony R Fletcher
2011-12-13 18:04         ` Jérémie Roquet
2011-12-13 18:20           ` Stephane Chazelas
2011-12-13 19:19             ` Anthony R Fletcher
2011-12-13 10:01 ` Peter Stephenson
2011-12-13 17:10   ` Bart Schaefer
2011-12-13 20:42     ` Rory Mulvaney
2011-12-13 17:45 ` Stephane Chazelas

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).