Bash 并行运行作业
我希望并行运行大量密集型进程,在这些进程中,我使用for循环遍历不同的参数。对类似问题的许多回答都提到可以使用xargs并行运行进程,但没有一个提到如果每个命令的参数发生变化,是否可以或如何做到这一点 例如(伪代码): 我想并行化intensiveCommandBash 并行运行作业,bash,parallel-processing,xargs,Bash,Parallel Processing,Xargs,我希望并行运行大量密集型进程,在这些进程中,我使用for循环遍历不同的参数。对类似问题的许多回答都提到可以使用xargs并行运行进程,但没有一个提到如果每个命令的参数发生变化,是否可以或如何做到这一点 例如(伪代码): 我想并行化intensiveCommand 或者有没有比使用xargs更简单的方法呢?我写了这篇文章,效果非常好——阅读顶部的评论,看看它是如何工作的 #!/bin/bash ####################################################
或者有没有比使用xargs更简单的方法呢?我写了这篇文章,效果非常好——阅读顶部的评论,看看它是如何工作的
#!/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
你可以用。它有一个--load
选项,用于避免计算机过载
parallel --load 100% ./intensiveCommand ::: 1 2 3 ::: 1 2 3
u芯数=4#在“每个芯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
#/bin/bash
#使用filedescriptor作为一种队列来填充处理槽。
执行3
您可以使用“intensiveCommand”在命令末尾添加和签名。这将在parralel中运行作业。是的,但这不考虑负载,对吗?因此,它将继续添加进程,因此它将开始交换进程并降低进程速度。在这种情况下,您可以从uname的输出中解析平均负载,并有条件地运行新进程。是的,安装和运行起来非常容易。其中的键函数为“BLPOP”,它对列表中的项目执行阻塞等待。这允许我精确地控制一次可以运行多少个进程。如果我想要8个,我会在开始的时候把8个项目放在列表中,每次我做一项工作的时候就拿一个,然后在完成后把它还给列表。有没有解释一下这是如何工作的pgrep-c“intensiveCommand”
统计当前运行的进程列表中“intensiveCommand”的实例数<代码>-ge
表示“大于或等于”。。。行(…)&
在后台启动某种新流程?除此之外,我对它的工作原理一无所知
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
#/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