2016-01-22 55 views
0

我創建了一個proc,它可能只是根據輸入而懸掛在那裏。現在我想爲它設置一個超時值,並強制它返回並在時間到期後繼續其他工作。TCL:超時一個可能掛起的proc

vwait的方式似乎不適用於我的情況在這裏。如果我把我的vwait PROC後,如:

after sometime set status timeout 
proc_may_hang 
vwait status 

如果PROC掛起時,vwait永遠不會被執行,事件循環從來沒有得到啓動和系統不知道或者監視變量狀態。

而且我也無法使用多線程來啓動監視進程。 TCL解釋器來自EDA軟件,Thread包不可用。

那麼有沒有辦法強制proc返回?非常感謝!

+3

會發生什麼樣的掛起事件? IO阻塞呼叫? – Dinesh

+0

@Dinesh對不起,不澄清這一點。這個過程只是因爲有大量的計算任務要做,而且即使經過很長時間也沒有任何迴應。 proc只包含一些計算命令。這在EDA軟件中發生了很多,如果發生掛起並跳到下一個,我想跳過這個工作。我希望我已經表達清楚。 –

+0

我的第一個想法是創建一個從解釋器並將計算推入該解釋器。看來殺死那個翻譯會更容易些。儘管如此,這可能是過度的。 –

回答

0

線程可以幫助,但需要一些連線。這是殺死長時間運行的線程的線程示例。

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 
+0

感謝您的回答!我已經嘗試了多線程,並且該方法失敗,因爲在EDA工具中我根本沒有Thread包。 :( –