bash is bad parallel language

Feb 07, 2013 15:18

В bash легко запустить несколько параллельных процессов, и затем дождаться их завершения:

some_program A &
some_program B &
some_program C &

wait
Эта простота портится тем, что при сбое в одном из параллельных процессов - нет возможности по простому об этом узнать ( Read more... )

shell

Leave a comment

Comments 12

jakobz February 7 2013, 16:40:23 UTC
А нельзя тулзу консольную написать, и через нее уже все пускать?

Reply

_winnie February 7 2013, 17:12:15 UTC
Вроде есть xargs, но приходится тогда изымать строчку кода в отдельный файл, и думать как проталкивать окружающие переменные и функции (через параметры или export не слишком коротко названных переменных, функции - тоже в отдельный файл).

Reply


justy_tylor February 7 2013, 18:34:40 UTC
Люди десятилетиями жрут кактус используют шелл, как после этого может что-то удивлять? :)

Reply


gegmopo4 February 7 2013, 19:05:22 UTC
Зачем xargs, если есть цикл?

Reply

_winnie February 7 2013, 19:50:14 UTC
В цикле надо записывать id-шники в массив, затем ещё итерироваться по нему в wait. В результате половина скрипта - не про задачу "запустить три процесса", а про синтаксис баша.

xargs можно попросить остановиться немедленно (exit 255):

(echo 'sleep 1; exit 255/sleep 12/sleep 12') | tr '/' '\0' |
xargs -P 10 -0 -t -n 1 bash -c

Меня кстати только что осенило, можно ещё попробовать make -j.

Reply

gegmopo4 February 8 2013, 16:44:49 UTC
Проблема ведь была в том, что с помощью xargs нельзя запустить функцию? Ну так и не надо, есть цикл, а xargs нужен для другого, когда цикл не подходит (не наш случай, по-видимому). С xargs встаёт проблема передачи переменных и возврата значения, а ведь именно борьбы с такими деталями вы и стараетесь избежать.

Reply


rvp74 February 7 2013, 20:57:48 UTC
Забавное совпадение. Как раз сегодня закончил имплементацию promise chaining на яве. Которая как раз и позволяет дождаться всех результатов, либо фэйла в одном из тасков. При этом прекрасно работает на фиксированном пуле с меньшим количеством тредов чем ждется результатов. :)

Reply


esyr February 8 2013, 06:02:27 UTC
Ну, для начала, $$ плохо, mktemp есть, в который что-то писать. Во-вторых, зачем все эти временные файлы, если можно просто выводить результат работы команд (если stdout и stderr заняты, то можно использовать exec для создания пайпов) и парсить его (так можно, например, делать сколь угодно сложную логику на основе завершения команд). А для убийства дерева процессов полезен pkill -P.

Reply

_winnie February 9 2013, 14:20:25 UTC
mktemp - однозначно лучше, спасибо, поменял

pkill -P - попробую у себя применить, наверное тоже лучше (у jobs -p + kill есть проблемы с racing conditions, на которые я уже наткнулся).

про результат работы команд - не очень понял, я хочу как можно проще - остановиться когда что-то не так, и потом по письму от робота разбираться в логах. Если надо разбираться в сортах ошибок - то наверное заменю (touch $FAIL) на (echo $? > $FAIL.prog_A). Такое бывает, правда редко (мало скриптов может протащить осмысленную разницу до exit code).

Reply

esyr February 9 2013, 14:49:23 UTC
Ну вот примерно такой говнокод:

(
(sleep 10 && echo "1 0" >&2 || echo "1 1" >&2;) &
( ( sleep 5; false; ) && echo "2 0" >&2 || echo "2 1" >&2;) &
) 2>&1 | while read cmd status
do
if [ "$status" != 0 ]
then
echo "cmd $cmd failed: $status."
# you can kill everything here
else
echo "cmd $cmd finished successfully."
fi
done

Тут нет принудительного включения line buffering и использования mkfifo вместо stderr и завёртывания говна с echo в отдельные функции, но идея такая. А так, завернуть всё вот это в подходящую функцию и ок.

Reply


Leave a comment

Up