LINUX.ORG.RU

Что-то многопоточный BASH странно работает?


0

0

Вот такой код:

#!/bin/bash
if (( PPID==1 )); then
echo "(son, pid=$$, ppid=$PPID) a=$a"
# for ((i=0; i<25; i++)); do echo -n '='; sleep 1; done
else
echo "(parent, pid=$$, ppid=$PPID) exporting variable a to my son..."
export a=34
$0 &
# for ((i=0; i<25; i++)); do echo -n '-'; sleep 1; done
fi

Ведет себя несколько странно... Иногда два раза вызывается часть else, а потом один раз if (то есть PPID становится равным единице), иногда работает, как ожидается: один раз отрабатывает предок, который запускает сам себя в фоне, а у фоновой копии процесса отрабатывает блок if, после чего скрипт завершается.
Вопросы:
1) Почему вообще у потомка в таком случае PPID равен 1-му, ведь это PID процесса init!
2) Почему иногда PPID первого порожденного потомка оказывается корректным, указывает на реального предка? И при этом второе порождение потомка (из этого, с нормальным PPID) всё равно будет считать своим предком процесс init!
3) Если вы раскомментируете два цикла for, получите бесконечное самопорождение процессов. Это как так вообще?

Заранее признателен, всю бошку уж сломал, это вам не fork'анье тупое в C, это вам высшая математика BASH'а :)

★★★★★

Тэкс, кажется, понял: те процессы, у которых PPID=1 - это так называемые зомби. Теперь понять бы ещё, как корректно завершить всю цепочку потомков...

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

> Тэкс, кажется, понял: те процессы, у которых PPID=1 - это так называемые зомби.

Зомби - это завершившийся процесс, который уже никак не сможет тебе напечатать, что у него PPID=1. Процесс переходит под init, когда завершается его родитель. Соответственно, у тебя часть процессов успевают отработать echo до того, как родитель отвалится, а часть нет.

const86 ★★★★★
()
Ответ на: комментарий от const86

Сорри, не зомби, а процессы-сироты... А как после запуска чего-то в форме:
ЧТО_ТО &
- узнать пид порожденного процесса?

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

>узнать пид порожденного процесса?
child_pid=$!
Тебе видимо нужно ждать завершения всех детей в родительском скрипте. Используй wait из баша без аргументов

nu11 ★★★★★
()
Ответ на: комментарий от nu11

Да, слабал я вот такой код теперь, весьма интересно работает (смотрите, в какой последовательности выводятся символы!):

#!/bin/bash
lstSymbols='=-+/?><'
max_count=5
count=${1:-0}
((count==0)) && rm -f /tmp/ppid.log
myChar=${lstSymbols:$count:1}
echo «$count: PPID=$PPID» >> /tmp/ppid.log
((++count>max_count)) && exit 0
$0 $count &
for ((i=0; i<100; i++)); do
echo -n $myChar
done
wait $!

Спасибо за советы :)

DRVTiny ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.