gpt4 book ai didi

bash - 如何从异步调用的函数中获取返回值

转载 作者:行者123 更新时间:2023-11-29 09:29:25 25 4
gpt4 key购买 nike

我有一个 bash 脚本,它从主模块异步调用两个函数,如下所示:

(func1 && print_msg f1) &
(func2 && print_msg f2) &

[...]

wait $(jobs -p)

如何从 func1 和 func2 返回一个值很容易并且经常被讨论。我的问题是如何在主模块中访问这些返回值以检查特定值。

最佳答案

如果您将退出状态 称为函数的“返回值”,那么使用wait 就很容易了。但是,如果您的函数返回比 8 位整数更复杂的东西,并且在将任务置于后台和返回值检索之间发生了很多事情,请继续阅读。

简单案例

您已经使用的 wait 内置函数返回它所等待的后台进程的退出状态(但前提是明确给出了 PID):

wait [..] waits for each process identified by an ID, which may be a process ID or a job specification, and reports its termination status. If ID is not given, waits for all currently active child processes, and the return status is zero.

例如:

$ f() { sleep 5; return 13; }
$ f &
$ wait $!
$ echo $?
13

更强大的同步

前面的例子是完全安全的,因为 $! 总是返回当前 shell 中最后一个后台进程的 PID,并且 f & 之间没有任何反应等待

在中间有一些工作的场景中:

f &
pid=$!
# work
wait "$pid"
ret=$?

f 的 PID(存储在 pid 中)有可能被回收——以防超过 pid_max 进程(在 Linux 上默认为 32768)在 work 部分 中产生的一些进程在 work 部分产生相同的PID(如 pid)。在那之前——因为 bash 缓存了它所有 child 的退出状态——f 的退出状态将被跟踪、存储和保存可用,即使 f 在您调用 wait "$pid" 之前 终止。

如果在上面的work 部分中有许多(和/或持久的)进程(可能在一个循环中),您可能想要使用更健壮的同步机制,或某种形式的 IPC,可能命名为管道/FIFO(使用 coproc 轻松设置)。

FIFO 可以传递结果,也可以发出后台作业完成的信号,因此您可以使用它代替 wait:

# fifo setup/clean-up
tmp=$(mktemp -td)
mkfifo "$tmp/f"
trap 'rm -rf "$tmp"' EXIT

# async f, push result to fifo
f() { sleep 5; echo "result" >"$tmp/f"; }
f &

# work

# block until f finishes, read result from fifo
f_ret=$(<"$tmp/f")
echo "f done, returned: $f_ret"

关于bash - 如何从异步调用的函数中获取返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47098783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com