简洁的问题解释:
我希望能够运行多个(我们会说几百个)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
and 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和朋友的理解可能有误,如有错误请指正。:)
另一种选择是以非阻塞形式运行作业提交,并让它将其完成传达回我的进程,但是在不同机器之间完成和协调它所需的进程间通信让我有点害怕。我希望在求助之前找到一个本地解决方案。
有没有我忽略的解决方案?