如何在限制进程数的同时并行化包含屏幕的for循环?

时间:2018-03-30 21:16:23

标签: bash parallel-processing gnu-screen

我在bash中有一个可并行化的for循环,并希望限制并行运行的作业数。脚本如下所示:

#!/usr/bin/env bash

num_cores=25
num_jobs=100

for ((i = 0; i < num_jobs; i++)); do
    while read -r -a curr_jobs < <(jobs -p -r) \
        && ((${#curr_jobs[@]} >= num_cores)); do
        wait -n
    done
    NAME=job_$i
    screen -S $NAME -d -m bash -c "my bash command"
done

该脚本基于the answer基于stackoverflow上的类似问题。但不同之处在于,当我在循环中调用Python时,在该答案中调用了screen。由于我不知道的某些原因,此解决方案看起来与screen不兼容。

如何修改脚本以限制并行screen会话数?

这个问题是否有更简单/更好的解决方案?

2 个答案:

答案 0 :(得分:1)

使用GNU Parallel和tmux

seq 100 | parallel -j25 -N0 --tmux my bash command

示例:为每个CPU核心运行一次休眠:

seq 100 | parallel --tmux "echo Running {} Job sequence {#}; sleep {}"

GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。

如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:

Simple scheduling

GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:

GNU Parallel scheduling

<强>安装

出于安全原因,您应该使用软件包管理器安装GNU Parallel,但如果没有为您的发行版打包GNU Parallel,则可以进行个人安装,这不需要root访问权限。这可以在10秒内完成:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解详情

查看更多示例:http://www.gnu.org/software/parallel/man.html

观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel

答案 1 :(得分:0)

前段时间我做过这样的事情:

#!/bin/bash 
FILE=$1
tmpVAR=0
while read line; do 
    ScriptTakingArgFromFile.sh $line & PID1=$!
    tmpVAR=$[$tmpVAR+1]
    if [ "$tmpVAR" -eq 50 ] 
        then tmpVAR=0
        # echo "STOP 50"
        wait $PID1
    fi
done < $FILE
wait $PID1

这将执行51个进程并停止。然后当进程号51结束时将触发另一个51。

如果您希望始终拥有一定数量的进程,则始终可以将pid写入数组,并在数组具有所需长度时停止。写入检查这些PID并在进程结束时从数组中删除它们,然后数组将收缩,另一个进程将被触发。

希望有所帮助。