在继续之前运行多个exec命令并等待完成

时间:2015-06-09 13:56:10

标签: background tcl exec tk

我知道我问了很多问题,我知道这里有很多关于我正在尝试做的事情,但是我无法让它在我的脚本中工作,也没弄清楚为什么它没有让我这样做。我试图在后台使用exec运行几个命令,测试范围可以在5到45分钟之间(如果必须提示许可证,则更长)。它需要永远运行它们,所以我想知道我需要做什么才能使我的脚本等待它们完成,然后继续下一部分脚本。

while {$cnt <= $len} {
# Begin count for running tests
set testvar [lindex $f $cnt]
if {[file exists $path0/$testvar] == 1} {
    cd $testvar
} else {
    exec mkdir $testvar
    cd $testvar
    exec create_symobic_link_here
}
# Set up test environment
exec -ignorestderr make clean
exec -ignorestderr make depends
puts "Running $testvar"
set runtest [eval exec -ignorestderr bsub -I -q lin_i make $testvar SEED=1 VPDDUMP=on |tail -n 1 >> $path0/runtestfile &]
cd ../
incr cnt
}

我知道这里没有任何东西可以让脚本等待进程完成但是我已经尝试了很多不同的东西,这是我可以让它运行一切的唯一方法。它不会等待。

1 个答案:

答案 0 :(得分:1)

一种方法是修改测试以创建“已完成”文件。无论测试是正确完成还是失败,都应创建此文件。

在开始测试之前修改启动循环以删除此文件:

//Initial setup
$(".post-details h2").each(function(){
    if($(this).height() > 21)
        $(this).addClass('margintop');
});

//On window resize
$(window).on("resize", ".post-details h2", function(){
    if($(this).height() > 21)
        $(this).addClass('margintop');
    else
        $(this).removeClass('margintop');
});

然后创建第二个循环:

 catch { file delete $path0/$testvar/finished }

如果任何一个测试没有创建'finished'文件,那么写入的循环将永远不会退出。所以我会添加一个额外的停止条件(不超过一小时)来退出循环。

另一种方法是将后台进程的进程id保存在列表中,然后第二个循环将检查每个进程id以查看它是否仍在运行。这种方法不需要对测试进行任何修改,但实现起来有点困难(在unix / mac上不太难,在Windows上更难)。

编辑:使用流程ID检查循环:

要使用进程ID,需要修改主循环以保存后台作业的进程ID:

在主循环开始之前,清除进程ID列表:

while { true } {
  after 60000
  set cnt 1 ; # ?
  set result 0
  while { $cnt <= $len } {
    set testvar [lindex $f $cnt]
    if { [file exists $path0/$testvar/finished] } {
      incr result
    }
    incr cnt
  }
  if { $result == $len } {
    break
  }
}

在主循环中,从exec命令保存进程ID(在tcl中,set pidlist {} 返回后台进程ID):

[exec ... &]

检查进程是否存在的过程(对于unix / mac)。 Tcl / Tk没有任何进程控制命令,因此使用unix'kill'命令。 unix上的'kill -0'仅检查进程是否存在,并且不影响进程的执行。

lappend pidlist $runtest ; # goes after the exec bsub...

检查测试是否完成的第二个循环变为:

# return 0 if the process does not exist, 1 if it does
proc checkpid { ppid } {
  set pexists [catch {exec kill -0 $ppid}]
  return [expr {1-$pexists}]
}

如果测试过程挂起并且永不退出,则此循环将永远不会退出,因此将使用总时间的第二个停止条件。