Last active
July 29, 2020 10:17
-
-
Save hell0again/f5f3064ad1ea6c5c7308 to your computer and use it in GitHub Desktop.
bashで並列処理
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# - (...) はサブプロセス実行 | |
# - & をつけるとコマンドをバックグラウンドプロセスとして起動する | |
# - wait ですべてのバックグラウンドプロセスを待機 | |
# - waitにプロセスidを渡すと指定したプロセスが終了するまで待機したうえで指定プロセスの戻り値を返す | |
# - プロセスidを渡さない場合、すべての子プロセスを待つが終了ステータスはつねに0になる。 | |
# - 子プロセスが0以外を返しても親プロセスはそれを検知できないので子プロセスの死亡を見て親プロセスを殺すのが難しい | |
# - プロセスidを複数渡すことはできない | |
( | |
sleep 1 | |
echo "exit first with 1" | |
exit 1 | |
)& | |
FIRST=$! | |
( | |
sleep 2 | |
echo "exit second with 2" | |
exit 2 | |
)& | |
SECOND=$! | |
wait $FIRST && wait $SECOND &&: | |
ST=$? | |
[ ${ST} -ne 0 ] && wait && exit ${ST} | |
# && だと1項目が0以外だと2項目以降は評価されない。 | |
# つまり wait $FIRST && wait $SECOND みたいな形だとfirstが0以外を返した時点で「終了が確定」する。 | |
# ただし終了が確定してもsecondのwaitを評価しないので他の子プロセスの実行が止まらなくなってしまう。 | |
# なので改めてpid指定なしのwaitで残りの子も待つ。 | |
# そうしないと先に親が死んで後で残りの子が死ぬ、みたいなことが起きてしまう。 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# いちいち変数名をつけたくないので配列に置き換え | |
# ついでにC-cを受付 | |
trap '[ 0 -lt $(jobs | wc -l) ] && kill -HUP $(jobs -p)' EXIT | |
wait_for_all(){ | |
local st=0 | |
for pid in $@; do | |
wait ${pid} &&: | |
(exit $?) && (exit ${st}) &&:; st=$? | |
done | |
[ ${st} -ne 0 ] && exit ${st} | |
} | |
PIDS=() | |
( | |
sleep 1 | |
echo "exit first with 1" | |
exit 1 | |
)& | |
PIDS+=($!) | |
( | |
sleep 2 | |
echo "exit first with 2" | |
exit 2 | |
)& | |
PIDS+=($!) | |
wait_for_all ${PIDS[@]} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment