2012-08-30 48 views
2

我是tcl的新手。我想在tcl中创建一个线程,它应该保持在后台调用自己。如何在tcl中创建线程8.4

#!/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为,但我不明白如何使用它

回答

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 

了解更多关于此in the examples

一些观察:

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

阅读this(及其链接)了解更多关于面向事件编程的信息。还有search wiki —它包含大量的例子和背景知识。

+0

感谢您的回复。但是,上面的代码也给我提供了同样的问题,即使串行端口上没有数据,它也不会从事件循环中出来并继续搜索事件。如果我有一些其他事件需要处理,那么在串行端口上没有数据时可能会发生这种情况。总之,上述两个代码都会阻止我的系统,并且不允许执行任何操作。你能明白我在这里说的意思吗?如果是,请帮助我 – user1497818

+0

不,我不明白你的意思。使用事件循环精确地允许您忘记忙于等待数据:当数据可用时,您设置了一个要调用的命令前缀。您可以在任何给定时间在任意数量的频道上安装任意数量的回调。他们不会干涉每一个人。请注意,没有“搜索事件”这样的事情。基本上,当你调用'vwait'时,你的代码将会有效地进入睡眠状态,并且只有在有回调被注册的事件时唤醒,并且回调才会被执行。 – kostix