TCL:超时可能挂起的进程



我创建了一个过程,根据输入,它可能只是挂在那里。现在我想为它设置一个超时值,并在时间结束后强制它返回并继续其他工作。

vwait方式似乎不适用于我在这里的情况。如果我把vwait放在我的proc之后,比如:

after sometime set status timeout
proc_may_hang
vwait status

如果 proc 挂起,vwait将永远不会被执行,事件循环永远不会启动,系统也不知道监视变量状态。

而且我也不能使用多线程来启动监视过程。TCL 解释器来自 EDA 软件,线程包不可用。

那么,有没有办法迫使proc回归呢?多谢!

线程

可以提供帮助,但需要一些连接。 下面是一个杀死长时间运行的线程的线程示例。

package require Thread
# Create a thread with needed procs for calculation.=.
proc spawn {} {
    set t_id [thread::create {
        # Source your program here.
        # Make sure to have thread::release when calculation is final.
        # source myfile.tcl
        # this is an example proc
        proc do_calculation {params} {
            # add this to your program
            # get your params for calculation from item
            foreach {parent_id callback index item} $params {}
            set i 10000
            while {$i > 0} {
                incr i $item
                if {$i > 99999} {
                    set i 10000
                }
            }
            # Run something when calculation is done here...
            puts "All done! i = $i"
            # Or in the parent thread in item_complete 
            thread::send -async $parent_id [list $callback $index $item]
            thread::release
        }
        # Don't change beleow. The thread::wait keeps the thread running
        # so can send it a command.
        thread::wait
    }]
}
proc check_thread {t_id seconds callback {started 0}} {
    # If the thread doesn't exist then it probably finished and called thread::release.
    if {[thread::exists $t_id] == 0} {
        $callback
        return
    }
    # Check the time remaining for the thread to complete.
    set now [clock seconds]
    if {$started == 0} {
        set started $now
    }
    set seconds_remaining [expr {$seconds - ($now - $started)}]
    puts "$seconds_remaining seconds remaining."
    # Stop the thread if it took too long.
    if {$seconds_remaining < 1} {
        puts "Times up... stopping thread `$t_id`."
        thread::release $t_id
        $callback
        return
    }
    # Check the thread again in 1 second.
    after 1000 [list check_thread $t_id $seconds $callback $started]
}
# some fake data. Package your data into a list of items to process.
set items [list 1 -1 9 -9 20 -20]
set items_i 0
proc next_item {} {
    global items
    global items_i
    if {$items_i < [llength $items]} {
        set item [lindex $items $items_i]
        incr items_i
        set t_id [spawn]
            # Tell the thread to run the calculation.
            thread::send -async $t_id [list do_calculation [list [thread::id] item_complete $items_i $item]]
        check_thread $t_id 10 next_item 
    } else {
        puts "Items completed. exiting."
        exit
    }   
}
proc item_complete {index item} {
    puts "Item #${index} completed successfully. Item = ${item}."
}
next_item
vwait forever

相关内容

  • 没有找到相关文章

最新更新