TCL:如何等待流程直到当前流程完成?

时间:2014-03-09 11:49:23

标签: tcl

  1. 我有一个不断更新的日志。
  2. 我正在运行生成文件的流程。此流程在后台运行,并且 更新日志说“[12:23:12:1] \ m成功完成(data_01)”。
  3. 一看到此评论,我就会将此文件用于下一个流程。
  4. 我创建了一个弹出窗口,说“等到日志说成功完成”,以避免 脚本进入下一个流程并中止。
  5. 但问题是每次我需要检查日志以查看该评论 在弹出窗口中单击“确定”。
  6. 有没有办法从更新日志中捕获评论。 我试过了

    set flag 0
    while { $flag == 0} {
        set fp [open  "|tail code.log" r]
        set data [ read $fp]
        close $fp
        set data [ split $data]
        if { [ regexp {.*successfully completed.*} $data ]} {
            set line $data
            set flag 1
        } else {
            continue
        }
    }
    
  7. 这个$line,我会将它传递给弹出变量,以便说等到 成功完成。我会说“成功完成”。 但是,由于打开的文件太多而且没有等待,这会引发错误。

2 个答案:

答案 0 :(得分:0)

您希望执行的操作是监控文件并等待,而不会挂起您要添加到文件中的特定行的UI。要做到这一点,您不能在文件上使用异步IO,因为Tcl文件总是可读的。相反,您需要在计时器上轮询该文件。在Tcl中,这意味着使用after命令。因此,创建一个命令来检查文件上次修改的时间,以及自上次检查文件后是否已更改,打开文件并查找特定数据。如果数据存在,请设置一些状态变量以允许程序继续执行下一步。如果没有,您只需使用after和适当的间隔安排另一次检查功能。

您可以像上面一样使用管道,但是当它可用时,您应该使用异步IO从通道读取数据。这意味着使用fileevent

答案 1 :(得分:0)

操作系统强加的进程可以一次打开的文件数量有限制。通常,如果你接近这个限制,那么你做的事情就错了!

所以让我们稍微回顾一下。

连续读取日志文件的最简单方法是从传入tail选项的程序-f打开管道,因此它只报告添加到文件中的内容而不是报告结束每次运行。像这样:

set myPipeline [open "|tail -f code.log"]

然后你可以从这个管道中读取,只要你不关闭它,你只会读一次。退出Tcl进程将关闭管道。您可以使用阻止gets来读取每一行,也可以使用fileevent,以便在行可用时获得回调。后一种形式是GUI的理想

阻止表格

while {[gets $myPipeline line] >= 0} {
    if {[regexp {successfully completed \(([^()]+)\)} $line -> theFlowName]} {
        processFlow $theFlowName
    }
}
close $myPipeline

回拨表格

假设管道保持阻塞模式。完全非阻塞有点复杂,但遵循类似的模式。

fileevent $myPipeline readable [list GetOneLine $myPipeline]
proc GetOneLine {pipe} {
    if {[gets $pipe line] < 0} {
        # IMPORTANT! Close upon EOF to remove the callback!
        close $pipe
    } elseif {[regexp {successfully completed \(([^()]+)\)} $line -> theFlowName]} {
        processFlow $theFlowName
    }
}

当这些形式出现在日志中时,这两种形式都会使用括号内的行提取位调用processFlow。这就是它不再是通用Tcl的部分......