我会尝试具体。这是OSX-Yosemite,Tcl 8.5.9。我做了类似的事情:
set fd [open "|$external"]
fconfigure $fd -blocking 0 -buffering line
fileevent $fd readable "set $tracername $fd"
这个tracername
包含一个全局变量的名称(带有基于名称空间的名称),接下来在这里使用:
# Ok, now clear the variable
set $tracername ""
# If vwait causes error, it may happen that the process
# has finished before it could be added to the event list
# (just the script had no opportunity to see it). If this
# happens, just go on, and in the next roll you'll find it out anyway.
$mkv::debug "--- Waiting for an event from any of fileevent-registered processes ($tracername)..."
catch {vwait $tracername}
$mkv::debug "--- UNBLOCKED BY: $tracername=[set $tracername]"
这在Linux和Cygwin上完美运行。在Mac上它停留在vwait
(据我所知)。
此catch
仅适用于所有"文件"来自fileevent已经关闭 - 根据文档,当没有事件被调度时执行vwait
导致类型错误异常(以防止永远等待)。但是我怀疑这是这种情况,因为启动的命令是一个C ++编译器命令调用,运行至少需要半秒以上。
该程序是make
工具的Tcl版本,此代码是并行构建支持的一部分。当我没有并行支持时运行会发生这种情况如果我同时运行至少2个进程,一切正常。
我在调试时观察到open |$external
生成的子进程停止在输出上打印任何东西,所以就像它已经完成了一样。但通常我生成了readable
个事件,这使我有机会检查是否[eof $fd]
并关闭它。