我有一个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。
答案 0 :(得分:1)
我可能是错的,但是我很确定你不要想要做到这一点。
我将在下面保留原始解决方案,但请使用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
原始文件存储版本
如果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/
答案 1 :(得分:1)
zsh随附zargs。为了对shell函数执行一些xargs式的并行操作,将很方便。
task () {
sleep $1
echo "hello $1"
}
arr=()
autoload -Uz zargs
arr=("${(@f)"$(zargs -P 3 -n 1 -- {3..1} -- task)"}")
print -l ${(qqq)arr}
#>> "hello 1"
#>> "hello 2"
#>> "hello 3"
这是zargs --help
的输出:
Usage: zargs [options --] [input-args] [-- command [initial-args]]
If command and initial-args are omitted, "print -r --" is used.
Options:
--eof[=eof-str], -e[eof-str]
Change the end-of-input-args string from "--" to eof-str. If
given as --eof=, an empty argument is the end; as --eof or -e,
with no (or an empty) eof-str, all arguments are input-args.
--exit, -x
Exit if the size (see --max-chars) is exceeded.
--help
Print this summary and exit.
--interactive, -p
Prompt before executing each command line.
--max-args=max-args, -n max-args
Use at most max-args arguments per command line.
--max-chars=max-chars, -s max-chars
Use at most max-chars characters per command line.
--max-lines[=max-lines], -l[max-lines]
Use at most max-lines of the input-args per command line.
This option is misnamed for xargs compatibility.
--max-procs=max-procs, -P max-procs
Run up to max-procs command lines in the background at once.
--no-run-if-empty, -r
Do nothing if there are no input arguments before the eof-str.
--null, -0
Split each input-arg at null bytes, for xargs compatibility.
--replace[=replace-str], -i[replace-str]
Substitute replace-str in the initial-args by each initial-arg.
Implies --exit --max-lines=1.
--verbose, -t
Print each command line to stderr before executing it.
--version
Print the version number of zargs and exit.
在上面的示例中,它使用--max-procs=max-procs, -P max-procs
和--max-args=max-args, -n max-args
。