我使用以下代码异步启动一些长时间运行的任务,但检测它是否在一开始就失败了:
sleep 0.3 &
long_running &
wait -n
# [Error handling]
# Do other stuff.
# Wait for completion of 'long_running'.
wait -n
# [Error handling]
如果我在等待长时间运行的孩子时使用SIGINT(使用Ctrl + C)脚本,则长时间运行的任务将继续并在完成后获得僵尸。 此外,父脚本消耗完整的CPU。我必须SIGKILL父母来摆脱这些过程。
我知道SIGINT是ignored by the child(这可能是它持续到完成的原因),但为什么父母会陷入这种混乱的状态?
如果我在收到SIGINT时杀死了孩子(下面注释的trap
),它会起作用(如预期的那样),但我想理解为什么它不起作用。
以下是完整的脚本。另请参阅https://gist.github.com/doak/08b69c500c91a7fade9f2c61882c93b4以获得更完整的示例/试用版:
#!/usr/bin/env bash
count="count=100000" # Adapt that 'dd' lasts about 3s. Comment out to run forever.
#fail=YES # Demonstrates failure of background task.
# This would work.
#trap "jobs -p | xargs kill" SIGINT
echo executing long running asynchronous task ...
sleep 0.3 &
dd if=/dev/zero$fail of=/dev/null bs=1M $count &
wait -n
errcode=$?
if test $errcode -ne -0; then
echo "failed"
exit $errcode
fi
echo waiting for completion ...
wait -n
errcode=$?
echo finished
exit $errcode
可能是我的问题与此C问题有关,但它讨论了系统调用wait()
:Possible for parent process to HANG on "wait" step if child process becomes a ZOMBIE or CRASHES?