我有一个 for 循环,其中调用了一个函数 task
。每次调用该函数都会返回一个附加到数组中的字符串。我想并行化这个 for 循环。我尝试使用 &
但它似乎不起作用。
这是未并行化的代码。
task (){ sleep 1;echo "hello $1"; }
arr=()
for i in {1..3}; do
arr+=("$(task $i)")
done
for i in "${arr[@]}"; do
echo "$i x";
done
输出为:
hello 1 x
hello 2 x
hello 3 x
太棒了!但现在,当我尝试将其与
并行时[...]
for i in {1..3}; do
arr+=("$(task $i)")&
done
wait
[...]
输出为空。
这个问题专门针对 zsh
,其 bash
对应问题请参见 here .
最佳答案
我可能是错的,但我很确定你不想这样做。
我将保留下面的原始解决方案,但尝试使用 coproc。
#! /usr/bin/zsh
coproc cat &
task(){
sleep $1
print -p "Sloppy simulation process # $1: $(date)"
}
arr=()
for i in {1..3}; do
task $i &
done
for i in {1..3}; do
read -p val
arr+=("$val")
done
for i in "${arr[@]}"; do
[[ -n "$i" ]] && echo "$i"
done
理想情况下,对 coproc 的写入将花费足够长的时间,以便读取首先开始并阻塞。
我认为。
我的输出:
Sloppy simulation process # 1: Thu Jul 26 15:19:02 CDT 2018
Sloppy simulation process # 2: Thu Jul 26 15:19:03 CDT 2018
Sloppy simulation process # 3: Thu Jul 26 15:19:04 CDT 2018
original file storing version
如果task
是一个长时间运行的步骤,那么可能值得并行工作并增加将其存储在持久性位置然后加载数组的开销。这个快速破解有帮助吗?
task(){ # task() handles persistence itself
sleep $1
echo "Sloppy simulation process # $1: $(date)" >| /tmp/task/$1
}
mkdir -p /tmp/task/
cd /tmp/task
for i in {1..3}
do task $i & # run them in background
done
wait # wait for the last one
arr=()
for f in *
do arr[$f]="$(<$f)" # read each into arr
done
for i in $( seq ${#arr[@]} )
do [[ -n "${arr[$i]}" ]] && echo "${arr[$i]}" # show them
done
rm -fr /tmp/task/
关于linux - 并行进程: appending outputs to an array in a zsh script,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51544688/