我有一个bash脚本,可以像这样异步调用主模块的两个函数:
(func1 && print_msg f1) &
(func2 && print_msg f2) &
[...]
wait $(jobs -p)
如何从func1和func2返回一个值很容易,并且经常被讨论过。我的问题是如何在主模块中访问这些返回值以检查特定值。
答案 0 :(得分:2)
如果您将退出状态称为功能""返回值",那么wait
就可以轻松实现。但是如果你的函数返回比8位整数更复杂的东西,并且在将任务放到后台和返回值检索之间发生了很多,请继续阅读。
您已使用的wait
内置函数返回它等待的后台进程的退出状态(但仅在显式给出PID时):
wait
[..]等待ID标识的每个进程,可能是进程ID或作业规范,报告其终止状态。如果未给出ID,则等待所有当前活动的子进程,并且返回状态为零。
例如:
$ f() { sleep 5; return 13; }
$ f &
$ wait $!
$ echo $?
13
上一个示例非常安全,因为$!
始终返回当前shell中最后一个后台进程的PID,f &
和wait
之间没有任何反应。
在两者之间有一些工作的场景中:
f &
pid=$!
# work
wait "$pid"
ret=$?
f
的PID(存储在pid
中)很可能会被回收 - 如果超过pid_max
个进程(默认为{{1}在32768
部分期间生成}} work
部分中生成的某些进程会收到相同的PID(work
)。在发生这种情况之前 - 并且因为pid
缓存其所有孩子的退出状态 - 即使bash
的退出状态也会被跟踪,存储和提供在调用f
之前,终止 。
如果您在上面的f
部分中有许多(和/或持久)进程(可能在循环中),您可能希望使用更强大的强健同步机制,或某种形式的IPC,可能是命名管道/ FIFO(可以轻松设置coproc
)。
FIFO可以提供结果,但也表示后台作业完成,因此您可以使用它代替wait "$pid"
:
work