Tcl中的事件循环

杜尔加·达塔(DurgaDatta)

我是Tcl的初学者。我正在尝试学习Tcl,而又不参与Tk。我遇到了类似这样的命令vwaitafter但是由于大多数解释都涉及event loopTk的概念,并且使我更加困惑因此我感到困惑我想了解事件和事件循环的概念,以及我提到的命令与它们之间的关系,请为此提供一些参考。外植体不应该以Tk为例,不使用Tcl扩展名,不具备事件先验知识。tcl事件循环的某些(最小)玩具示例和实际wordl应用程序,不包括GUI编程/ Tk,将不胜感激。

在Tclers Wiki上遇到了本教程我正在寻找其他类似的参考或解释。

多纳研究员

如果不使用Tk,则使用事件循环的主要原因是在执行其他一些I / O绑定任务时在后台等待,以及处理服务器套接字。

让我们看一下服务器套接字。

当您使用以下方法打开服务器套接字时:

socket -server myCallbackProcedure 12345

您正在安排在服务器套接字上设置事件处理程序,以便在有传入连接时,该连接将转换为您的普通套接字,并调用您提供的回调过程(myCallbackProcedure)来处理与套接字的交互。通常,这通常是通过设置fileevent处理程序来完成的,以便在传入数据到达时对其进行处理,而不是阻塞等待它的进程,但这不是必须的。

事件循环?这是一段代码在调用操作系统(通过select()poll()WaitForMultipleObject(),等,这取决于操作系统和编译选项)要等到事情发生在任何指定的通道或发生超时。这非常有效,因为可以在等待时挂起进行调用的线程。如果发生某种情况,则OS调用返回,并且Tcl安排要调用的相关回调。(内部有一个队列。)这是一个循环,因为一旦处理了事件,通常回去等待一些事件。(这是Tk所做的,直到没有更多可控制的窗口vwait为止,并且直到某个事件处理程序设置了它正在等待的变量为止,该做什么。)

异步等待是使用按时间排序的队列进行管理的,并转换为在OS中设置呼叫超时。

一个例子:

socket -server myCallbackProcedure 12345
proc myCallbackProcedure {channel clientHost clientPort} {
    puts "Connection from $clientHost"
    puts $channel "Hi there!"
    flush $channel
    close $channel
}
vwait forever
# The “forever” is an idiom; it's just a variable that isn't used elsewhere
# and so is never set, and it indicates that we're going to run the process
# until we kill it manually.

异步连接处理的一个更复杂的示例,因此我们可以一次为多个连接提供服务(所需的CPU:最少):

socket -server myCallbackProcedure 12345
proc myCallbackProcedure {channel clientHost clientPort} {
    puts "Connection from $clientHost"
    fileevent $channel readable [list incoming $channel $clientHost]
    fconfigure $channel -blocking 0 -buffering line
    puts $channel "Hi there!"
}
proc incoming {channel host timeout} {
    if {[gets $channel line] >= 0} {
        puts $channel "You said '$line'"
    } elseif {[eof $channel]} {
        puts "$host has gone"
        close $channel
    }
}
vwait forever

甚至更复杂的示例将在连接上的最后一条消息之后10秒(= 10000ms)关闭连接:

socket -server myCallbackProcedure 12345
proc myCallbackProcedure {channel clientHost clientPort} {
    global timeouts
    puts "Connection from $clientHost"
    set timeouts($channel) [after 10000 [list timeout $channel $clientHost]]
    fileevent $channel readable [list incoming $channel $clientHost]
    fconfigure $channel -blocking 0 -buffering line
    puts $channel "Hi there!"
}
proc incoming {channel host timeout} {
    global timeouts
    after cancel $timeouts($channel)
    if {[gets $channel line] >= 0} {
        puts $channel "You said '$line'"
    } elseif {[eof $channel]} {
        puts "$host has gone"
        close $channel
        unset timeouts($channel)
        return
    }
    # Reset the timeout
    set timeouts($channel) [after 10000 [list timeout $channel $host]]
}
proc timeout {channel host} {
    global timeouts
    puts "Timeout for $host, closing anyway..."
    close $channel
    unset -nocomplain timeouts($channel)
}
vwait forever

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

tcl中的嵌套foreach循环

来自分类Dev

错误:TCL Ffile中的for循环

来自分类Dev

什么是React中的事件循环?

来自分类Dev

在jQuery中循环动作/事件

来自分类Dev

Qt中的libuv事件循环

来自分类Dev

JavaScript中的事件循环模型

来自分类Dev

什么是React中的事件循环?

来自分类Dev

在点击事件中添加for循环

来自分类Dev

scxml 事件中的循环调用

来自分类Dev

如何从tcl中的foreach循环返回值

来自分类Dev

RuntimeError:事件循环在异步python中关闭

来自分类Dev

For循环未在订阅事件中执行

来自分类Dev

我在pygame中的事件循环有问题

来自分类Dev

RuntimeError:事件循环在异步python中关闭

来自分类Dev

播放事件将在videojs中无限循环

来自分类Dev

在循环VBA中输出重复事件

来自分类Dev

Nodejs 中的非阻塞事件循环

来自分类Dev

事件循环如何处理JavaScript中的事件处理程序?

来自分类Dev

事件循环如何处理JavaScript中的事件处理程序?

来自分类Dev

TCL ::如何使用TCL中的while循环从10到1打印数字(如何减少变量值)

来自分类Dev

TCL ::如何使用TCL中的while循环从10到1打印数字(如何减少变量值)

来自分类Dev

tcl:循环并使用Regex提取

来自分类Dev

在wxPython应用程序中实现我自己的事件循环

来自分类Dev

DLL中子应用程序中的C ++事件循环

来自分类Dev

在Ruby中建立事件循环时,如何避免无限递归?

来自分类Dev

Node.JS中的事件循环如何可预测

来自分类Dev

是否允许从错误事件中循环返回?-BPMN

来自分类Dev

Qt应用程序中的线程和事件循环

来自分类Dev

Python中的`await`是否会产生事件循环?