使用TCL超时

发布于 2024-08-24 05:24:21 字数 192 浏览 2 评论 0原文

TCL 有没有办法将一段代码包含在超时块中?我的意思是,即使执行未完成,该块也会在特定超时后退出。 例如:-

timeout (interval) {
#wait for socket connection here

}

如果在间隔时间内没有建立连接,则块退出。

谢谢和问候, 安贾利

Is there a way in TCL to enclose a piece of code in a timeout block? What I mean by that is that the block will exit after a particular timeout even if the execution is not complete.
For instance:-

timeout (interval) {
#wait for socket connection here

}

If no connection is established in interval time, the block exits.

Thanks and Regards,
Anjali

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绿萝 2024-08-31 05:24:22

安贾利,
您正在寻找 vwait

这是一个示例:等待五秒钟以连接到服务器套接字,否则关闭套接字并继续运行脚本:

# Initialise the state
after 5000 set state timeout
set server [socket -server accept 12345]
proc accept {args} {
   global state connectionInfo
   set state accepted
   set connectionInfo $args
}

# Wait for something to happen
vwait state

# Clean up events that could have happened
close $server
after cancel set state timeout

# Do something based on how the vwait finished...
switch $state {
   timeout {
      puts "no connection on port 12345"
   }
   accepted {
      puts "connection: $connectionInfo"
      puts [lindex $connectionInfo 0] "Hello there!"
   }
}

编辑
您需要使用 非阻塞 I/O< 与 UART 设备进行通信/a>.

Anjali,
You are looking for vwait.

Here is an example: Wait five seconds for a connection to a server socket, otherwise close the socket and continue running the script:

# Initialise the state
after 5000 set state timeout
set server [socket -server accept 12345]
proc accept {args} {
   global state connectionInfo
   set state accepted
   set connectionInfo $args
}

# Wait for something to happen
vwait state

# Clean up events that could have happened
close $server
after cancel set state timeout

# Do something based on how the vwait finished...
switch $state {
   timeout {
      puts "no connection on port 12345"
   }
   accepted {
      puts "connection: $connectionInfo"
      puts [lindex $connectionInfo 0] "Hello there!"
   }
}

Edit
You will need to communicate with your UART device using non blocking I/O.

深府石板幽径 2024-08-31 05:24:22

我知道这是一个老问题,每隔几年我都会被同样的问题绊倒。我想提供 vwait 的替代方案,因为实际上没有必要,尽管有一些重要的警告尚未指出。这是专门针对串行 i/o 期间的超时,如原始问题所示。这是摘录。我知道完整的代码更好,但无论如何,所有 I/O 对于您的设备来说都是唯一的。

set port /dev/ttyUSB0
set TIMEOUT 1000

### Important: this MUST be a global variable, even if
### it's only used in this subroutine 
global waitFlag

### for timeouts to work, need non-blocking i/o on the port
if {[catch {open $port "RDWR"} fh]} {
  puts stderr "Cannot open $port"}
  return "error"
  }
fconfigure $fh -mode 38400,n,8,1 -buffering none -blocking 0

### In this example, remote device responds with "<OK>" when
### "<RS>" is sent, though it may take a few read operations
### to get the full string. Your protocol may vary.

puts -nonewline $fh "<RS>"
flush $fh

set waitFlag 1
### create a timeout: after a while, flag will change value
set timeout [after $TIMEOUT {set waitFlag 0}]

set response ""
set n -1
while {$n == -1} {
  ### 10ms delay between successive reads, no point going faster than
  ### your serial i/o. Fine tune for speed and size of packets.
  after 10
  append response [read $fh]
  ### keep reading until the closing ">" arrives ...
  set n [string first > $response]
  ### ... or the waitFlag changes to indicate timeout
  ### Important: without an "update", the delayed change in waitFlag
  ### will not propagate back.
  update
  if { $waitFlag == 0 } {break}
  }
close $fh

### Important: a successful read needs to cancel the pending timeout
### otherwise it may hang around and time out unexpectedly on the next
### communication.
if {$waitFlag == 0} { return "timeout" }\
else                { after cancel $timeout; return $response }

I know this is an old question, every few years I keep tripping over the same issues. I want to offer an alternative to vwait because, in fact, it is not necessary, though there are a couple of important caveats which have not been pointed out. This is specifically targeting timeouts during serial i/o, as in the original question. It's an excerpt. I know complete code is preferable, but all i/o will be unique to your device, anyway.

set port /dev/ttyUSB0
set TIMEOUT 1000

### Important: this MUST be a global variable, even if
### it's only used in this subroutine 
global waitFlag

### for timeouts to work, need non-blocking i/o on the port
if {[catch {open $port "RDWR"} fh]} {
  puts stderr "Cannot open $port"}
  return "error"
  }
fconfigure $fh -mode 38400,n,8,1 -buffering none -blocking 0

### In this example, remote device responds with "<OK>" when
### "<RS>" is sent, though it may take a few read operations
### to get the full string. Your protocol may vary.

puts -nonewline $fh "<RS>"
flush $fh

set waitFlag 1
### create a timeout: after a while, flag will change value
set timeout [after $TIMEOUT {set waitFlag 0}]

set response ""
set n -1
while {$n == -1} {
  ### 10ms delay between successive reads, no point going faster than
  ### your serial i/o. Fine tune for speed and size of packets.
  after 10
  append response [read $fh]
  ### keep reading until the closing ">" arrives ...
  set n [string first > $response]
  ### ... or the waitFlag changes to indicate timeout
  ### Important: without an "update", the delayed change in waitFlag
  ### will not propagate back.
  update
  if { $waitFlag == 0 } {break}
  }
close $fh

### Important: a successful read needs to cancel the pending timeout
### otherwise it may hang around and time out unexpectedly on the next
### communication.
if {$waitFlag == 0} { return "timeout" }\
else                { after cancel $timeout; return $response }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文