我的问题是如何更改此代码,以便它只使用4个线程/子进程?
TESTS="a b c d e"
for f in $TESTS; do
t=$[ ( $RANDOM % 5 ) + 1 ]
sleep $t && echo $f $t &
done
wait
Run Code Online (Sandbox Code Playgroud)
Lyn*_*nch 36
有趣的问题.我尝试使用xargs,我找到了一种方法.
试试这个:
seq 10 | xargs -i --max-procs=4 bash -c "echo start {}; sleep 3; echo done {}"
Run Code Online (Sandbox Code Playgroud)
--max-procs=4 将确保一次运行不超过四个子进程.
输出将如下所示:
start 2
start 3
start 1
start 4
done 2
done 3
done 1
done 4
start 6
start 5
start 7
start 8
done 6
done 5
start 9
done 8
done 7
start 10
done 9
done 10
Run Code Online (Sandbox Code Playgroud)
请注意,执行顺序可能不遵循您提交顺序中的命令.如你所见,2开始于1之前.
mob*_*mob 13
快速而肮脏的解决方案:在for循环内的某处插入此行:
while [ $(jobs | wc -l) -ge 4 ] ; do sleep 1 ; done
Run Code Online (Sandbox Code Playgroud)
(假设您还没有在同一个shell中运行其他后台作业)
Lyn*_*nch 10
我找到了这个问题的另一个解决方案parallel(moreutils包的一部分.)
parallel -j 4 -i bash -c "echo start {}; sleep 2; echo done {};" -- $(seq 10)
Run Code Online (Sandbox Code Playgroud)
-j 4 代表 -j maxjobs
-i 使用参数{}
-- 划定你的论点
该命令的输出将是:
start 3
start 4
start 1
start 2
done 4
done 2
done 3
done 1
start 5
start 6
start 7
start 8
done 5
done 6
start 9
done 7
start 10
done 8
done 9
done 10
Run Code Online (Sandbox Code Playgroud)
你可以使用jobs内置函数做这样的事情:
for f in $TESTS; do
running=($(jobs -rp))
while [ ${#running[@]} -ge 4 ] ; do
sleep 1 # this is not optimal, but you can't use wait here
running=($(jobs -rp))
done
t=$[ ( $RANDOM % 5 ) + 1 ]
sleep $t && echo $f $t &
done
wait
Run Code Online (Sandbox Code Playgroud)
GNU Parallel 专为此类任务而设计:
TESTS="a b c d e"
for f in $TESTS; do
t=$[ ( $RANDOM % 5 ) + 1 ]
sem -j4 sleep $t && echo $f $t
done
sem --wait
Run Code Online (Sandbox Code Playgroud)
观看介绍视频以了解更多信息:
http://www.youtube.com/playlist?list=PL284C9FF2488BC6D1