使用Perl等待许多并行shell命令

时间:2013-10-23 18:42:41

标签: multithreading perl shell cluster-computing

简明问题解释:

我希望能够运行多个(我们会说几百个)shell命令,每个命令都会启动一个长时间运行的进程并阻塞几小时或几天,最多只有一行或两行输出(这个命令只是向集群提交的作业)。这个阻塞是有帮助的,所以我可以准确地知道每个结束的时间,因为我想调查每个结果,并可能多次重新运行,以防它们失败。我的程序将作为这些程序的一种控制器。

for all commands in parallel {
    submit_job_and_wait()
    tries = 1
    while ! job_was_successful and tries < 3{
        resubmit_with_extra_memory_and_wait()
        tries++
    }
}

我尝试/调查的内容:

我到目前为止认为最好为每个提交创建一个线程,它只是阻止等待输入。有足够的内存用于相当多的等待线程。但是根据我的阅读,perl线程比其他语言更接近重复进程,因此创建数百个它们是不可行的(也感觉不对)。

似乎还有各种各样的事件循环协作系统,如AnyEventCoro,但这些似乎要求你依赖异步库,否则你不能真正做到任何事情。我无法弄清楚如何使用它制作多个shell命令。我尝试过使用AnyEvent::Util::run_cmd,但在提交了多个命令之后,我必须指定我想要等待它们的顺序。我事先并不知道每次提交需要多长时间,所以我不能recv,有时候不会非常不走运。这并不是真的平行。

my $cv1 = run_cmd("qsub -sync y 'sleep $RANDOM'");
my $cv2 = run_cmd("qsub -sync y 'sleep $RANDOM'");

# Now should I $cv1->recv first or $cv2->recv? Who knows!
# Out of 100 submissions, I may have to wait on the longest one before processing any.

我对AnyEvent和朋友的理解可能有误,所以如果是这样请纠正我。 :)

另一种选择是以非阻塞形式运行作业提交,并将其完成传回给我的进程,但是在不同的机器上完成和协调它所需的进程间通信让我有点沮丧。我希望在诉诸之前找到一个本地解决方案。

有没有我忽略的解决方案?

1 个答案:

答案 0 :(得分:0)

您更愿意使用fireworkspegasus等科学工作流程软件,这些软件旨在帮助科学家将大量计算工作提交给共享或专用资源。但它们也可以做得更多,所以它可能对你的问题有点过分,但它们仍然值得一看。

如果您的目标是尝试找到工作中最严格的内存要求,您也可以简单地提交大量或请求内存的作业,然后从会计中提取实际内存使用量(qacct),或者,群集策略允许,登录运行作业的计算节点,并使用topps查看内存使用情况。