我希望能够运行多个(我们会说几百个)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线程比其他语言更接近重复进程,因此创建数百个它们是不可行的(也感觉不对)。
似乎还有各种各样的事件循环协作系统,如AnyEvent
和Coro
,但这些似乎要求你依赖异步库,否则你不能真正做到任何事情。我无法弄清楚如何使用它制作多个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和朋友的理解可能有误,所以如果是这样请纠正我。 :)
另一种选择是以非阻塞形式运行作业提交,并将其完成传回给我的进程,但是在不同的机器上完成和协调它所需的进程间通信让我有点沮丧。我希望在诉诸之前找到一个本地解决方案。
有没有我忽略的解决方案?