bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: multi-threaded compiling


From: Greg Wooledge
Subject: Re: multi-threaded compiling
Date: Tue, 12 Mar 2024 07:29:50 -0400

On Tue, Mar 12, 2024 at 02:15:38PM +0700, Robert Elz wrote:
>     Date:        Mon, 11 Mar 2024 17:25:57 -0400
>     From:        Chet Ramey <chet.ramey@case.edu>
>     Message-ID:  <322e10a6-3808-49be-aa9d-a1d367a90572@case.edu>
> 
>   | OK, here's the longer answer. When the shell is interactive, and job
>   | control is enabled, the shell prints job completion notifications to
>   | stdout at command boundaries.
> 
> which is, IMO, yet another bogus bash misfeature.  That should
> happen, with the effect described, but only when PS1 is about
> to be printed - precisely so commands like the one described
> will work.   Sigh.
> 
> There aren't many complaints about this misfeature of bash,
> as almost no-one writes interactive command lines where it makes
> a difference.   That doesn't mean they should not be able to.

Yeah, it appears you're right.  In a script, this works as expected:

hobbit:~$ cat foo
#!/bin/bash
for i in {0..3}; do sleep 1 & done
for i in {0..3}; do
    wait -n -p pid; e=$?
    printf 'pid %s status %s\n' "$pid" "$e"
done
hobbit:~$ ./foo
pid 530359 status 0
pid 530360 status 0
pid 530361 status 0
pid 530362 status 0


But interactively, *even with bash -c and set +m*, it just fails:

hobbit:~$ bash -c 'set +m; for i in {0..3}; do sleep 1 & done; for i in {0..3}; 
do wait -n -p pid; e=$?; printf "pid %s status %s\n" "$pid" "$e"; done'
pid 530407 status 0
pid 530410 status 0
pid  status 127
pid  status 127

Looks like a race condition, where some of the children get reaped and
tossed away before "wait -n -p pid" has a chance to grab their status.

If I stick a "sleep 2" in between the two loops, then it's even worse:

hobbit:~$ bash -c 'set +m; for i in {0..3}; do sleep 1 & done; sleep 2; for i 
in {0..3}; do wait -n -p pid; e=$?; printf "pid %s status %s\n" "$pid" "$e"; 
done'pid  status 127
pid  status 127
pid  status 127
pid  status 127

ALL of the children are discarded before the second loop has a chance to
catch a single one of them.  This is clearly not working as expected.

Using "bash +i -c" doesn't change anything, either.  Or "bash +i +m -c".
Whatever magic it is that you get by putting the code in an actual
script, I can't figure out how to replicate it from a prompt.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]