Linux 并行运行shell脚本

Linux 并行运行shell脚本,linux,bash,shell,unix,parallel-processing,Linux,Bash,Shell,Unix,Parallel Processing,我有一个shell脚本 洗牌大文本文件(600万行6列) 根据第一列对文件进行排序 输出1000个文件 所以伪代码看起来像这样 file1.sh #!/bin/bash for i in $(seq 1 1000) do Generating random numbers here , sorting and outputting to file$i.txt done 有没有办法以并行运行此shell脚本来充分利用多核CPU 目前,./file1.sh以1到1000次的顺序执

我有一个shell脚本

  • 洗牌大文本文件(600万行6列)
  • 根据第一列对文件进行排序
  • 输出1000个文件
  • 所以伪代码看起来像这样

    file1.sh 
    
    #!/bin/bash
    for i in $(seq 1 1000)
    do
    
      Generating random numbers here , sorting  and outputting to file$i.txt  
    
    done
    
    有没有办法以
    并行运行此shell脚本来充分利用多核CPU

    目前,.
    /file1.sh
    以1到1000次的顺序执行,速度非常慢


    感谢您的帮助。

    要使事情并行运行,请在shell命令末尾使用“&”在后台运行,然后默认情况下,
    wait
    将等待所有后台进程完成。所以,也许并行启动10个,然后等待,然后再执行另一个10个。您可以使用两个嵌套循环轻松完成此操作。

    请检查,这些循环可用于并行运行脚本的部分

    我尚未对此进行测试,但这可能是一个开始:

    #!/bin/bash
    for i in $(seq 1 1000)
    do
       ( Generating random numbers here , sorting  and outputting to file$i.txt ) &
       if (( $i % 10 == 0 )); then wait; fi # Limit to 10 concurrent subshells.
    done
    wait
    

    另一个非常方便的方法是使用,如果您还没有安装,那么它非常值得安装;如果任务不一定需要相同的时间,这是非常宝贵的

    seq 1000 | parallel -j 8 --workdir $PWD ./myrun {}
    
    将启动
    /myrun 1
    /myrun 2
    等,确保一次运行8个作业。如果您想同时在多个节点上运行,它还可以获取节点列表,例如在PBS作业中;我们向用户提供的关于如何在系统上执行此操作的说明如下


    更新为添加:您希望确保您使用的是gnu并行,而不是moreutils包中提供的更有限的同名实用程序(描述了两者的不同历史)。

    有一个简单的可移植程序可以为您做到这一点:。PPSS会自动为您安排作业,方法是检查有多少内核可用,并在每次另一个作业刚刚完成时启动另一个作业。

    在GNU parallel的文档中,有一个可以从shell并行运行作业的工具,它甚至包括作业之间的比较。有很多很多解决方案。另一个好消息是,它们在调度作业方面可能非常有效,因此所有的内核/处理器都会一直处于忙碌状态。

    生成随机数很容易。 假设你有一个像商店数据库这样的大文件,你想在某个特定的基础上重写这个文件。 我的想法是计算内核的数量,将文件拆分为多少个内核,生成一个script.cfg文件,split.sh和recombine.sh split.sh将文件拆分为多少个内核,clone script.cfg(用于更改这些巨大文件中的内容的脚本),clone script.cgf将文件拆分为多少个内核,使其可执行,在克隆中搜索并替换一些变量,这些变量必须知道文件要处理的部分 并在后台运行它们 克隆完成时,生成一个克隆$core.ok文件,因此,当所有克隆完成时,只有在生成所有.ok文件时,才会通知循环将部分结果重新组合为单个结果。 可以用“等等”来完成,但我喜欢我的方式

    看看底部,部分翻译为英语 通过这种方式,我可以在2分钟内处理20000篇包含16列的文章(四核),而不是8列(单核) 您必须关心CPU温度,因为所有内核都以100%的空闲率运行
    IDLE_CPU=1
    NCPU=$(nproc)
    
    int_childs() {
        trap - INT
        while IFS=$'\n' read -r pid; do
            kill -s SIGINT -$pid
        done < <(jobs -p -r)
        kill -s SIGINT -$$
    }
    
    # cmds is array that hold commands
    # the complex thing is display which will handle all cmd output
    # and serialized it correctly
    
    trap int_childs INT
    {
        exec 2>&1
        set -m
    
        if [ $NCPU -gt $IDLE_CPU ]; then
            for cmd in "${cmds[@]}"; do
                $cmd &
                while [ $(jobs -pr |wc -l) -ge $((NCPU - IDLE_CPU)) ]; do
                    wait -n
                done
            done
            wait
    
        else
            for cmd in "${cmds[@]}"; do
                $cmd
            done
        fi
    } | display
    
    NCPU=$(nproc) int_childs(){ 陷阱整数 而IFS=$'\n'读取-r pid;执行 kill-s SIGINT-$pid 完成<&1 set-m 如果[$NCPU-gt$IDLE_CPU];则 对于“${cmds[@]}”中的cmd,请执行以下操作 $cmd& 而[$(jobs-pr | wc-l)-ge$((NCPU-IDLE_CPU))];do 等等 完成 完成 等待 其他的 对于“${cmds[@]}”中的cmd,请执行以下操作 $cmd 完成 fi }|显示
    您可能想看看
    runp
    是一个简单的命令行工具,可以并行运行(shell)命令。当您希望同时运行多个命令以节省时间时,它非常有用。它很容易安装,因为它是一个二进制文件。它已经在Linux(amd64和arm)和MacOS/darwin(amd64)上进行了测试。

    如果您发现自己需要在shell脚本中编写任何非琐碎的东西(例如,多处理等),那么是时候用适当的编程语言重新编写它了。这将并行启动所有千项任务,这可能会导致太多的交换/争用,以获得最佳的工作吞吐量,但这肯定是一种合理且简单的开始方式。这一点很好!最简单的解决方案是使用一个外部循环来限制已启动的子shell的数量,并在它们之间等待。@Anders:或者在上面的循环中的“完成”之前插入一个“if($i%10==0));然后等待;fi…@Tony:我认为将其保留在其中是有意义的<代码>等待没有运行子shell似乎没有任何作用,如果选择的并发子shell数量不是要运行的任务数量的一个因素,我们可能会在循环结束时得到仍在运行的活动子shell。如果所有作业占用完全相同的时间,此解决方案效果最佳。如果这些作业占用的时间不相同,您将浪费CPU时间等待其中一个长作业完成。换言之:它不会一直保持10个作业同时运行。非常感谢您的建议。所有CPU现在都在工作。你知道如何让它在节点间运行吗?我正在使用PBS将作业提交给高性能计算,节点数为2:ppn=8,但只有一个节点在工作。@Tony:直到现在我才听说PBS。。。听起来很有趣,但我不知道如何使用它。很抱歉有关PBS问题和跨节点的问题,请参阅。等待是如何工作的?你能用一个例子更新你的答案吗?我想在某个函数中运行几个线程,但在所有线程完成之前,下一个函数不能启动。@d-b
    wait
    等待后台进程完成,而不是线程。例如,
    用于文件在magnage.txt massible.log magnific.xml中;是否创建scp$文件someuser@somehost:/tmp/&;完成;等待echo“完成”
    将运行三个
    scp
    (安全公司