我有一个这样的脚本:
#!/bin/bash
for i=1 to 200000
do
create input file
run ./java
done
我需要同时运行一个(8或16)个进程(java)并且我不知道如何操作。我知道wait
可能会有所帮助,但它应该一直运行8个进程,而不是等到前8个进程完成另一个8进程。
答案 0 :(得分:4)
bash
4.3为wait
命令-n
添加了一个有用的新标记,导致wait
阻止,直到任何单个后台作业,而不仅仅是给定子集(或所有)的成员,以完成。
#!/bin/bash
cores=8 # or 16, or whatever
for ((i=1; i <= 200000; i++))
do
# create input file and run java in the background.
./java &
# Check how many background jobs there are, and if it
# is equal to the number of cores, wait for anyone to
# finish before continuing.
background=( $(jobs -p) )
if (( ${#background[@]} == cores )); then
wait -n
fi
done
存在一个小的竞争条件:如果您处于最大负载但是在之后完成作业,则运行jobs -p
,您仍将阻止直到另一个工作
完成。你无能为力,但在实践中不应该有太多麻烦。
在bash
4.3之前,您需要定期轮询后台作业集,以查看池何时降至阈值以下。
while :; do
background=( $(jobs -p))
if (( ${#background[@]} < cores )); then
break
fi
sleep 1
done
答案 1 :(得分:2)
像这样使用GNU Parallel
,简化为20个作业而不是200,000个,第一个作业是echo
而不是&#34;创建文件&#34; 和第二个作业工作是sleep
而不是&#34; java&#34; 。
seq 1 20 | parallel -j 8 -k 'echo {}; sleep 2'
-j 8
说明一次要运行多少个工作。 -k
表示保持输出顺序。
这是一个输出的小动画,所以你可以看到时间/顺序:
答案 2 :(得分:1)
使用非古老版本的GNU实用程序或在* BSD / OSX上,使用xargs
和-P
选项并行运行进程。
#!/bin/bash
seq 200000 | xargs -P 8 -n 1 mytask
其中mytask is an auxiliary script, with the sequence number (the input line) available as the argument
$ 1`:
#!/bin/bash
echo "Task number $1"
create input file
run ./java
如果需要,您可以将所有内容放在一个脚本中:
#!/bin/bash
seq 200000 | xargs -P 8 -n 1 sh -c '
echo "Task number $1"
create input file
run ./java
' mytask
如果您的系统没有seq
,则可以使用bash代码段
for ((i=1; i<=200000; i++)); do echo "$i"; done
或其他shell工具,例如
awk '{for (i=1; i<=200000; i++) print i}' </dev/null
或
</dev/zero tr '\0' '\n' | head -n 200000 | nl