在Tcl中使用 trace 和 vwait 等待命令结束

@ 2010-03-17 18:13:17
标签:

    有时,我们需要等待某个操作的完成。这里的操作可以用一个Tcl命令来代替。使用 trace 和 vwait 可以完成这个事情。

    #-------------------------------------------
    # Usage:
    #  use trace to wait some command to finish
    #-------------------------------------------
    
    namespace eval ::noyesno::testing {
    
        proc _traceProc { args } {
            set name [lindex $args 0 0]
            set op   [lindex $args end]
    
            set waitVar [namespace current]::[regsub -all {::} $name "__"]
    
    	set time [clock format [clock seconds] -format "%H:%M:%S"]
            switch $op {
              "enter" { puts "DEBUG: $time $args" }
              "leave" {
                incr $waitVar
    	    puts "DEBUG: $time $args"
              }
            }
        }
    
        proc waitmgr { op name {val 0}} {
          set waitVar [namespace current]::[regsub -all {::} $name "__"]
    
          switch $op {
    	"init"   {
                set $waitVar 0
                puts "DEBUG: install wait for $name"
                trace add execution $name leave [namespace current]::_traceProc
                trace add execution $name enter [namespace current]::_traceProc
    	}
            "remove" {
    	    trace remove execution $name leave [namespace current]::_traceProc
    	    trace remove execution $name enter [namespace current]::_traceProc
                unset $waitVar
    	}
            "set" {
                set $waitVar $val
    	}
          }
        }
    
        proc wait { name {sec {4000}} {expect ""}} {
          set waitVar [namespace current]::[regsub -all {::} $name "__"]
    
          if {$expect != "" && [set $waitVar] == $expect} {
            puts "DEBUG: already finished"
            return
          }
    
          puts "DEBUG: trace start: $name = [set $waitVar]"
          after $sec   set $waitVar -1
          vwait $waitVar
          after cancel set $waitVar -1
    
          if { [set $waitVar] < 0 } {
                puts "INFO: **TIMEOUT** wait $name = [set $waitVar]"
          } else {
                puts "INFO: **OK**      wait $name = [set $waitVar]"
          }
          return $waitVar
        }
    }
    
    # Usage Demo
    proc proc_hello {args} {puts "inside proc_hello"}
    
    after 2000 proc_hello
    after 4000 proc_hello
    ::noyesno::testing::waitmgr  init proc_hello
    ::noyesno::testing::wait     proc_hello 3000
    ::noyesno::testing::wait     proc_hello 3000 2
    
    after 5000 proc_hello
    ::noyesno::testing::wait     proc_hello 3000
    
    
    标签:

      分享到:
      comments powered by Disqus

      26/30ms