如何通过多线程运行bash脚本

如何通过多线程运行bash脚本

我有 bash 脚本,它创建高能碰撞事件,如果一个事件需要大约 2 分钟,那么对于 100000 个事件则需要 200000 分钟,这太多了。所以如果我在一个节点中有50个核心,我希望每个核心上都有一个事件,这样在2分钟内就会生成50个事件,这样就节省了时间。我认为这可以通过多线程或任何其他方式来完成,那么有人可以帮助我吗?

答案1

GNU Parallel 就是为此类任务而设计的。

seq 100000 | parallel do_experiment

如果您的实验采用不同类型的值(例如模型),那么您可以通过以下方式运行所有模型的所有实验:

seq 100000 | parallel do_experiment --iteration {1} --model {2} :::: - ::: model1 model2

默认情况下,每个 CPU 核心有 1 个进程,并确保两个并行作业的输出不会混合。如果您的实验室中有多台未使用的计算机,您也可以让它们参与计算。

GNU Parallel 是一个通用并行器,可以轻松地在同一台计算机或多台您可以通过 ssh 访问的计算机上并行运行作业。它通常可以代替for循环。

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

简单的调度

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

GNU 并行调度

安装

如果您的发行版未打包 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

答案2

您可以将作业作为后台进程启动,直到达到后台 50 个作业的限制,然后等待一项作业完成,然后再启动另一项作业。

LIMIT=50
while collision_event_to_run
do 
    run_new_collision_event&

    while (( $(jobs | wc -l) >= LIMIT ))
    do
                sleep 1
    done

done

或者更好地在平均负载较低时运行新事件。

LIMIT=49
while collision_event_to_run
do 
    run_new_collision_event&
    sleep 2   # let time for the load average calculation

    while (( $(cut -d " " -f1 < /proc/loadavg) >= LIMIT ))
    do
                sleep 1
    done

done

另一种选择是使用该batch命令将作业堆叠到atd批处理队列中。

batch collision _event_1
batch collision _event_2
batch collision _event_3
...

atd服务将并行启动作业,直到服务器负载达到限制。该限制是 的一个参数,例如,它必须在服务启动脚本 atd中设置。atdatd -l 50

编辑:

  • 为操作系统保留一点空闲CPU atd -l 49

  • atd 每分钟都会启动一个新作业,这太慢了,无法让服务器达到最后 200 万个作业的负载。您可以通过该参数减少延迟-batd -b 2 -l 49每 2 秒启动一项作业将允许在第一个作业完成之前达到限制。

相关内容