2

我是 tcl 的新手。我想在 tcl 中创建一个线程,它应该在后台继续调用自己。

#!/usr/bin/env tclsh

set serPort [open "/dev/ttyS0" RDWR]

fconfigure $serPort  -mode 115200,n,8,1 -blocking 0 

while { 1 } {
set data [gets  $chan]
puts $data

}

我想避免使用上面的 while 循环,并为 while 循环内的功能创建一个可重复的线程。基本上,我将 PC 的 COM1 连接到设备并从设备获取串行数据。但是,如果端口上没有数据,即使我使用“eof”命令,它仍然不会脱离循环。这就是我想创建线程的原因。

我打算为此使用 Tcl_CreateThread 但我不明白如何使用它

4

1 回答 1

5

不要那样做。相反,使用通常的 Tcl 惯用语来处理非阻塞通道:为“通道可读”事件设置一个处理程序,然后进入事件循环;当设备将数据发送到您打开的端口时,操作系统会将数据传递给您的应用程序并调用回调。

演示该概念的最小程序如下所示:

proc my_read_handler ch {
    set data [read $ch]
    if {[eof $ch]} {
        close $ch
        set ::forever done ;# this makes the call to `vwait` below to quit
        return
    }
    # Otherwise process the data here ...
}

set serPort [open "/dev/ttyS0" RDWR]

fconfigure $serPort -mode 115200,n,8,1 -blocking no
fileevent $serPort readable [list my_read_handler $serPort]

vwait ::forever ;# the program enters the event loop here

在示例中阅读更多相关信息。

几个观察:

  • EOF 仅在远程端关闭时发生。如果您close在您的频道上调用,在这种情况下甚至不会调用“可读”。
  • 如果你正在编写一个 Tk 应用程序,它已经有一个事件循环,所以不需要调用vwait(此外,强烈建议不要这样做,因为这会重新进入事件循环):你只需打开你的设备,例如,在用户单击按钮时执行的代码中,在获取的通道上设置可读回调,然后在该回调中执行其余处理(如上所示)。

阅读本文(以及那里的链接)以获取有关面向事件编程的更多信息。还可以搜索wiki——它包含大量示例和背景知识。

于 2012-08-30T14:05:37.753 回答