Bash:在多个核心上运行相同的程序

时间:2013-03-11 16:24:13

标签: linux bash parallel-processing multiprocessing

我可以访问一台可以访问10个内核的机器 - 我想实际使用它们。我习惯在自己的机器上做的事情是这样的:

for f in *.fa; do
  myProgram (options) "./$f" "./$f.tmp"
done

我有10个文件我想这样做 - 让我们称之为blah00.fa,blah01.fa,... blah09.fa。

这种方法的问题是myProgram一次只使用1个核心,并且在多核机器上这样做我一次使用1个核心10次,所以我不会使用我的mahcine到它的最大能力。

我怎样才能更改我的脚本,以便它同时运行我的所有10个.fa文件?我看了Run a looped process in bash across multiple cores,但是我无法从那里得到命令来做我想要的事。

4 个答案:

答案 0 :(得分:9)

您可以使用

for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
done
wait

将并行启动所有作业,然后等到所有完成后再继续。如果你有比核心更多的工作,你可以启动所有这些工作,并让你的操作系统调度程序担心交换进程。

一项修改是一次启动10个工作

count=0
for f in *.fa; do
    myProgram (options) "./$f" "./$f.tmp" &
    (( count ++ ))        
    if (( count = 10 )); then
        wait
        count=0
    fi
done

但这不如使用parallel,因为你不能像旧的那样开始新工作,而且在你设法开始10个工作之前,你也无法检测到旧工作是否完成。 wait允许您等待单个特定进程或所有后台进程,但不会让您知道何时完成任意一组后台进程。

答案 1 :(得分:6)

使用GNU Parallel,您可以:

parallel myProgram (options) {} {.}.tmp ::: *.fa

来自:http://git.savannah.gnu.org/cgit/parallel.git/tree/README

=完全安装=

完全安装GNU Parallel非常简单:

./configure && make && make install

如果您不是root用户,可以在路径中添加〜/ bin并安装 〜/ bin和〜/ share:

./configure --prefix=$HOME && make && make install

或者,如果您的系统缺少“制作”。你可以简单地复制src / parallel src / sem src / niceload src / sql到你路径中的一个目录。

=最小安装次数=

如果你只是需要并行而没有制作'安装(也许是 系统是旧的或Microsoft Windows):

wget http://git.savannah.gnu.org/cgit/parallel.git/plain/src/parallel
chmod 755 parallel
cp parallel sem
mv parallel sem dir-in-your-$PATH/bin/

观看介绍视频以了解详情:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

答案 2 :(得分:3)

您是否考虑过使用Parallel

答案 3 :(得分:0)

# Wait while instance count less than $3, run additional instance and exit
function runParallel () {
    cmd=$1
    args=$2
    number=$3
    currNumber="1024"
    while true ; do
        currNumber=`ps -e | grep -v "grep" | grep " $1$" | wc -l`
        if [ $currNumber -lt $number ] ; then
            break
        fi
        sleep 1
    done
    echo "run: $cmd $args"
    $cmd $args &
}

loop=0
# We will run 12 sleep commands for 10 seconds each 
# and only five of them will work simultaneously
while [ $loop -ne 12 ] ; do
    runParallel "sleep" 10 5
    loop=`expr $loop + 1`
done