我想并行运行大量密集进程,其中我使用for循环遍历不同的参数。对类似问题的一些答案提到并行运行进程可以使用xargs完成,但是如果每个命令的参数都发生变化,它们似乎都没有提及是否或如何做到这一点。
作为示例(伪代码):
for paramA in 1 2 3
for paramB in 1 2 3
./intensiveCommand $paramA $paramB
end
end
我想平行强化命令
或者使用xargs有更简单的方法吗?
答案 0 :(得分:2)
您可以使用GNU parallel。它有一个--load
选项,可以避免计算机过载。
parallel --load 100% ./intensiveCommand ::: 1 2 3 ::: 1 2 3
答案 1 :(得分:1)
number_of_cores=4 #<-- number of processorcores, in my case: 4
for paramA in 1 2 3
do
for paramB in 1 2 3
do
#========== automatic load regulator ==================
sleep 1
while [ $( pgrep -c "intensiveCommand" ) -ge "$number_of_cores" ]
do
kill -SIGSTOP $$
done
#======================================vvvvvvvvvvvvvvvv
( ./intensiveCommand $paramA $paramB ; kill -SIGCONT $$ ) &
done
done
如果存在与核心一样多的密集命令,则此程序将自行置于保持。完成的密集命令将让程序继续(参见 kill -SIGCONT $$ )。 程序再次检查并启动密集命令,直到再次达到最大密集命令数时再次锁定。
睡眠是为了克服在一个密集命令的启动和它在流程表中出现之间的延迟。
答案 2 :(得分:1)
“每个核心1个插槽”的调度非常紧凑,坚固而简单。
#/bin/bash
#use the filedescriptor as a kind of queue to fill the processing slots.
exec 3< <(
for PARAM_A in 1 2 3
do
for PARAM_B in 1 2 3
do
echo $PARAM_A $PARAM_B
done
done
)
#4 seperate processing slots running parallel
while read -u 3 PARA PARB; do "intensiveCommand $PARA $PARB" ; done &
while read -u 3 PARA PARB; do "intensiveCommand $PARA $PARB" ; done &
while read -u 3 PARA PARB; do "intensiveCommand $PARA $PARB" ; done &
while read -u 3 PARA PARB; do "intensiveCommand $PARA $PARB" ; done &
#only exit when 100% sure that all processes ended
while pgrep "intensiveCommand" &>"/dev/null" ; do wait ; done
答案 3 :(得分:0)
我写的这个非常好用 - 阅读顶部的评论,看看它是如何工作的。
#!/bin/bash
################################################################################
# File: core
# Author: Mark Setchell
#
# Primitive, but effective tool for managing parallel execution of jobs in the
# shell. Based on, and requiring REDIS.
#
# Usage:
#
# core -i 8 # Initialise to 8 cores, or specify 0 to use all available cores
# for i in {0..63}
# do
# # Wait for a core, do a process, release core
# (core -p; process; core -v)&
# done
# wait
################################################################################
function usage {
echo "Usage: core -i ncores # Initialise with ncores. Use 0 for all cores."
echo " core -p # Wait (forever) for free core."
echo " core -v # Release core."
exit 1
}
function init {
# Delete list of cores in REDIS
echo DEL cores | redis-cli > /dev/null 2>&1
for i in `seq 1 $NCORES`
do
# Add another core to list of cores in REDIS
echo LPUSH cores 1 | redis-cli > /dev/null 2>&1
done
exit 0
}
function WaitForCore {
# Wait forever for a core to be available
echo BLPOP cores 0 | redis-cli > /dev/null 2>&1
exit 0
}
function ReleaseCore {
# Release or give back a core
echo LPUSH cores 1 | redis-cli > /dev/null 2>&1
exit 0
}
################################################################################
# Main
################################################################################
while getopts "i:pv" optname
do
case "$optname" in
"i")
if [ $OPTARG -lt 1 ]; then
NCORES=`sysctl -n hw.logicalcpu`; # May differ if not on OSX, maybe "nproc" on Linux
else
NCORES=$OPTARG
fi
init $NCORES
;;
"p")
WaitForCore
;;
"v")
ReleaseCore
;;
"?")
echo "Unknown option $OPTARG"
;;
esac
done
usage
举例来说,以下需要10秒钟(而不是80秒)来完成16次等待,每次5秒钟:
core -i 8
for i in {0..15}
do
# Wait for a core, do a process, release core
(core -p ; sleep 5 ; core -v)&
done
wait