开发者

background loop problem

I'm in process of extending my knowledge of bash scripting. I came across following snippet:

!/bin/bash
# background-loop.sh

for i in 1 2 3 4 5 6 7 8 9 10            # First loop. 
do
  echo -n "$i "
done & # Run this loop in background.
   # Will sometimes execute after second loop.

echo   # This 'echo' sometimes will not display.

for i in 11 12 13 14 15 16 17 18 19 20   # Second loop.
do
  echo -n "$i "
done  

echo word   # This 'echo' sometimes will not display.

It seems that this snippet output is non deterministic; and I would like to know why...

edit: so far; in 10 attempts "word" was always shown

edit2: sample outputs:

11 1 12 13 14 2 15 3 16 4 17 5 18 6 19 7 20 8 9 word
1 11 12 13 2 14 3 15 4 16 5 17 6 18 7 19 8 20 9 10 word
11 1开发者_开发百科2 13 14 1 15 16 17 2 18 3 19 4 20 5 6 word


A loop, or any command, that runs in the background is run concurrently with the rest of the script. It might run on a different processor if you have a multi-core machine. The order in which things are depends on your number of cores, how busy the system is and the whims of the operating system scheduler.

With large amounts of I/O from multiple processes to the same terminal/file/whatever, you might even see outputs being mixed up.


Basically what is happening here is that you have 2 processes running at the same time. And as always in such case you cannot predict in which order they will execute. Every combination of output from first for loop and second for loop is possible.


You can wait on bg tasks in scripts as follows:

# create a sentinel for exiting (is this the right term?)
export sentinel=".stopBgTask.$$"
# Run in the background and wait for sentinel to be created
i=1
while [ ! -e "$sentinel" ]
do echo $i
   i=$(($i + 1))
   sleep 1
done & # uncomment the & when you have no script errors

echo "Parent sleeping for a few seconds"
sleep 3
echo "stop the background task" > $sentinel
echo "Waiting for bg task to end..."
wait $! # wait for last bg task to end (kill $! would work too)
rm $sentinel
echo "We are done!"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜